This commit is contained in:
freedakgmail
2025-11-22 23:49:24 +08:00
parent b83382b604
commit c033e46782
3580 changed files with 1745279 additions and 2428 deletions
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 Florian Cassayre
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -0,0 +1,74 @@
# read-gedcom
![](https://github.com/arbre-app/read-gedcom/actions/workflows/build.yml/badge.svg)
![](https://img.shields.io/npm/v/read-gedcom?color=brightgreen)
![](https://img.shields.io/librariesio/dependents/npm/read-gedcom)
![](https://img.shields.io/npm/l/read-gedcom?color=brightgreen)
***A Gedcom file reader written in Typescript.*** See the **[documentation](https://docs.arbre.app/read-gedcom/)**.
### Features
* Tolerant parsing
* Character encoding detection (ASCII, CP1252, UTF-8, UTF-16, CP850, and more)
* Good effort of parsing and interpreting non-standard data
* Near full specification coverage
* Mostly Gedcom 5.5.5 compliant while being as much backward compatible as possible
* Parser for dates in any standard calendars
* Unopinionated API
* We provide the API, but the user has full control over the interpretation of the data
* It's also possible to not use the API, in which case it can be shaken off the tree
* Strongly typed
* Zero dependencies; compatible on browser and Node.js
* Less than `20kB` gzipped
* ...and more:
* Conversion of dates
* Serialization-friendly
* Progress tracking for larger files
### Installation and Usage
```
npm install read-gedcom
```
```javascript
import { readGedcom } from 'read-gedcom';
const promise = fetch('https://mon.arbre.app/gedcoms/royal92.ged')
.then(r => r.arrayBuffer())
.then(readGedcom);
promise.then(gedcom => {
console.log(gedcom.getHeader().toString());
});
```
Or, if you simply want to include it as a javascript file, this is also possible:
```html
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/read-gedcom/dist/read-gedcom.min.js"></script>
<script>
const promise = fetch('https://mon.arbre.app/gedcoms/royal92.ged')
.then(r => r.arrayBuffer())
.then(Gedcom.readGedcom);
promise.then(gedcom => {
console.log(gedcom.getHeader().toString());
});
</script>
```
### Documentation
* **[Quick Start](https://docs.arbre.app/read-gedcom/pages/Getting%20Started/quickstart)**
* **[Basic Examples](https://docs.arbre.app/read-gedcom/pages/Getting%20Started/basic-examples)**
* **[Advanced Examples](https://docs.arbre.app/read-gedcom/pages/Getting%20Started/advanced-examples)**
* **[API](https://docs.arbre.app/read-gedcom/modules)**
### Bug report
A Gedcom file isn't parsed correctly? Please [open a ticket](https://github.com/arbre-app/read-gedcom/issues)!
Also make sure to attach a zipped version of the bogus Gedcom file.
If you don't want to publicly share the file, you may send it to [this email address](https://github.com/arbre-app); we will create a minimal reproducible example based on what you sent us, which can be safely shared.
@@ -0,0 +1,5 @@
export * from './tree';
export * from './selection';
export * from './parse';
export * from './tag';
export * from './value';
@@ -0,0 +1,22 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./tree"), exports);
__exportStar(require("./selection"), exports);
__exportStar(require("./parse"), exports);
__exportStar(require("./tag"), exports);
__exportStar(require("./value"), exports);
//# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,yCAAuB;AACvB,8CAA4B;AAC5B,0CAAwB;AACxB,wCAAsB;AACtB,0CAAwB"}
@@ -0,0 +1,5 @@
/**
* This annotation controls the enumerability of a property.
* @param value
*/
export declare const enumerable: (value: boolean) => (target: any, prop: string, descriptor?: PropertyDescriptor) => void;
@@ -0,0 +1,25 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.enumerable = void 0;
/**
* This annotation controls the enumerability of a property.
* @param value
*/
const enumerable = (value) =>
// eslint-disable-next-line
(target, prop, descriptor) => {
if (descriptor) {
descriptor.enumerable = value;
}
else {
const propSymbol = Symbol(prop);
Object.defineProperty(target, prop, {
configurable: true,
enumerable: value,
get() { return this[propSymbol]; },
set(value) { this[propSymbol] = value; },
});
}
};
exports.enumerable = enumerable;
//# sourceMappingURL=decorators.js.map
@@ -0,0 +1 @@
{"version":3,"file":"decorators.js","sourceRoot":"","sources":["../../../src/meta/decorators.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACI,MAAM,UAAU,GAAG,CAAC,KAAc,EAAE,EAAE;AACzC,2BAA2B;AAC3B,CAAC,MAAW,EAAE,IAAY,EAAE,UAA+B,EAAE,EAAE;IAC3D,IAAI,UAAU,EAAE;QACZ,UAAU,CAAC,UAAU,GAAG,KAAK,CAAC;KACjC;SAAM;QACH,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE;YAChC,YAAY,EAAE,IAAI;YAClB,UAAU,EAAE,KAAK;YACjB,GAAG,KAAK,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YAClC,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;SAC3C,CAAC,CAAC;KACN;AACL,CAAC,CAAC;AAdO,QAAA,UAAU,cAcjB"}
@@ -0,0 +1,2 @@
export { enumerable } from './decorators';
export { AnyFunction, AnyConstructor, Mixin } from './mixins';
@@ -0,0 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.enumerable = void 0;
var decorators_1 = require("./decorators");
Object.defineProperty(exports, "enumerable", { enumerable: true, get: function () { return decorators_1.enumerable; } });
//# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/meta/index.ts"],"names":[],"mappings":";;;AAAA,2CAA0C;AAAjC,wGAAA,UAAU,OAAA"}
@@ -0,0 +1,12 @@
/**
* A type representing an arbitrary function.
*/
export declare type AnyFunction<A = any> = (...input: any[]) => A;
/**
* A type representing an arbitrary constructor.
*/
export declare type AnyConstructor<T = {}> = new (...args: any[]) => T;
/**
* A type representing a mixin function.
*/
export declare type Mixin<T extends AnyFunction> = InstanceType<ReturnType<T>>;
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=mixins.js.map
@@ -0,0 +1 @@
{"version":3,"file":"mixins.js","sourceRoot":"","sources":["../../../src/meta/mixins.ts"],"names":[],"mappings":""}
@@ -0,0 +1,55 @@
import { FileEncoding } from './decoder';
import { GedcomReadingPhase } from './GedcomReadingPhase';
/**
* Options to control the parsing of the Gedcom tree.
*/
export interface GedcomReadingOptions {
/**
* When set to <code>true</code> completely disabled the indexing in the tree.
* This option can be safely set without affecting the correctness of the other components that may use the tree.
* However, it will incur a slowdown when querying the tree.
*/
noIndex?: boolean;
/**
* When set to <code>true</code> the backwards references of the root node will not be stored (namely spouse and sibling relationships).
* This option only has an effect when {@link noIndex} is not set, and as for that option it will not affect correctness of other components.
* It will incur a slowdown when querying backward references.
*/
noBackwardsReferencesIndex?: boolean;
/**
* When set to <code>true</code> the {@link Tag.Concatenation} and {@link Tag.Continuation} special tags will not get interpreted and will be preserved in the resulting tree.
* This option might affect the behavior of other components.
* Otherwise the tags will get inlined according to their respective semantics, and thus will never appear in the output.
*/
noInlineContinuations?: boolean;
/**
* When set to <code>true</code> all the {@link TreeNode} in the tree will be frozen and modifications will be forbidden by the runtime.
* Otherwise the objects will remain normal.
* This option is not enabled by default for performance reasons.
*/
doFreeze?: boolean;
/**
* An optional callback used to track the progress.
* Can also be used to implement preemptive multitasking (unblock the rendering thread).
* @param phase The current phase
* @param progress The progress of the phase, indicated by a number between <code>0</code> and <code>1</code>, or <code>null</code> if the progress cannot be determined
*/
progressCallback?: (phase: GedcomReadingPhase, progress: number | null) => void;
/**
* When set, disables the automatic charset detection mechanism and forces the parser to decode the file using the specified charset.
* This is an escape hatch and its usage is not recommended; if you encounter issues with the detection mechanism please open a ticket instead.
*/
forcedCharset?: FileEncoding;
/**
* When set to <code>true</code>, illegally encoded data will raise an exception.
* This can occur when dealing with ANSEL encoded data.
* The default behavior is the insertion of a unicode replacement character.
*/
doStrictDecoding?: boolean;
/**
* When set to <code>true</code>, the {@link TreeNode._index} attribute will be non-enumerable.
* As a consequence, {@link JSON.stringify} will not serialize the index.
* It is however still possible to recompute the index, by calling {@link indexTree}.
*/
doHideIndex?: boolean;
}
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=GedcomReadingOptions.js.map
@@ -0,0 +1 @@
{"version":3,"file":"GedcomReadingOptions.js","sourceRoot":"","sources":["../../../src/parse/GedcomReadingOptions.ts"],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
/**
* Reading phases.
*/
export declare const enum GedcomReadingPhase {
Decoding = 0,
TokenizationAndStructuring = 1,
Indexing = 2,
Freezing = 3
}
@@ -0,0 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GedcomReadingPhase = void 0;
/**
* Reading phases.
*/
var GedcomReadingPhase;
(function (GedcomReadingPhase) {
GedcomReadingPhase[GedcomReadingPhase["Decoding"] = 0] = "Decoding";
GedcomReadingPhase[GedcomReadingPhase["TokenizationAndStructuring"] = 1] = "TokenizationAndStructuring";
GedcomReadingPhase[GedcomReadingPhase["Indexing"] = 2] = "Indexing";
GedcomReadingPhase[GedcomReadingPhase["Freezing"] = 3] = "Freezing";
})(GedcomReadingPhase = exports.GedcomReadingPhase || (exports.GedcomReadingPhase = {}));
//# sourceMappingURL=GedcomReadingPhase.js.map
@@ -0,0 +1 @@
{"version":3,"file":"GedcomReadingPhase.js","sourceRoot":"","sources":["../../../src/parse/GedcomReadingPhase.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACH,IAAkB,kBAKjB;AALD,WAAkB,kBAAkB;IAChC,mEAAQ,CAAA;IACR,uGAA0B,CAAA;IAC1B,mEAAQ,CAAA;IACR,mEAAQ,CAAA;AACZ,CAAC,EALiB,kBAAkB,GAAlB,0BAAkB,KAAlB,0BAAkB,QAKnC"}
@@ -0,0 +1,50 @@
/**
* Supported Gedcom file encoding schemes.
*/
export declare const enum FileEncoding {
Utf8 = "UTF-8",
Ansel = "ANSEL",
Cp1252 = "Cp1252",
Macintosh = "Macintosh",
Cp850 = "Cp850",
Utf16be = "UTF-16be",
Utf16le = "UTF-16le"
}
/**
* Early detectable file metadata.
* Can be used to infer the file encoding with high confidence.
*/
export interface FileMetadata {
/**
* The source encoding value, as defined in the header.
*/
sourceEncoding: string | null;
/**
* The source provider value, as defined in the header.
*/
sourceProvider: string | null;
/**
* The source provider's version value, as defined in the header.
*/
sourceProviderVersion: string | null;
/**
* Whether this file contains a byte order marker (BOM).
*/
fileHasBOM: boolean;
}
/**
* Extracts the file metadata (see {@link FileMetadata}). The metadata can then be used to guess the actual charset of the file.
* To circumvent the bootstrapping problem this function restricts its reading to the first lines of the file only, and
* decodes them as UTF-8.
* @param buffer The content of the file
* @param maxPeekBytes Maximum number of bytes to read
* @param maxPeekLines Maximum number of lines to read
*/
export declare const getFileMetadata: (buffer: ArrayBuffer, maxPeekBytes?: number, maxPeekLines?: number) => FileMetadata;
/**
* Detects the file charset using a set of heuristics. Has proven to work great in practice.
* If you encounter a file for which this procedure doesn't work as intended please do open an issue
* at: https://github.com/arbre-app/read-gedcom/issues.
* @param buffer The content of the file
*/
export declare const detectCharset: (buffer: ArrayBuffer) => FileEncoding;
@@ -0,0 +1,146 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.detectCharset = exports.getFileMetadata = exports.FileEncoding = void 0;
const tokenizer_1 = require("./tokenizer");
const structurer_1 = require("./structurer");
const decoding_1 = require("./decoding");
/**
* Supported Gedcom file encoding schemes.
*/
var FileEncoding;
(function (FileEncoding) {
FileEncoding["Utf8"] = "UTF-8";
FileEncoding["Ansel"] = "ANSEL";
FileEncoding["Cp1252"] = "Cp1252";
FileEncoding["Macintosh"] = "Macintosh";
FileEncoding["Cp850"] = "Cp850";
FileEncoding["Utf16be"] = "UTF-16be";
FileEncoding["Utf16le"] = "UTF-16le";
})(FileEncoding = exports.FileEncoding || (exports.FileEncoding = {}));
/**
* Extracts the file metadata (see {@link FileMetadata}). The metadata can then be used to guess the actual charset of the file.
* To circumvent the bootstrapping problem this function restricts its reading to the first lines of the file only, and
* decodes them as UTF-8.
* @param buffer The content of the file
* @param maxPeekBytes Maximum number of bytes to read
* @param maxPeekLines Maximum number of lines to read
*/
const getFileMetadata = (buffer, maxPeekBytes = 5000, maxPeekLines = 200) => {
const { output: inputHead, bomCharset } = (0, decoding_1.decodeUtfBOM)(buffer.slice(0, maxPeekBytes)); // Start with UTF-8 since file can contain a BOM
const hasBOM = bomCharset !== null;
const it = (0, tokenizer_1.tokenize)(inputHead, false); // Non-strict mode: break silently on error
let i = 0;
const array = [];
for (const line of it) {
if (i >= maxPeekLines) {
break;
}
array.push(line);
i += 1;
}
const tree = (0, structurer_1.buildTree)(array);
const header = tree.children.filter(c => c.tag === "HEAD" /* Tag.Header */);
const char = header.flatMap(c => c.children.filter(n => n.tag === "CHAR" /* Tag.Character */ || n.tag === "CHARACTER" /* TagNonStandard.CharacterAlt */));
const charOpt = char.length > 0 ? char[0].value : null;
const source = header.flatMap(c => c.children.filter(n => n.tag === "SOUR" /* Tag.Source */));
const sourceOpt = source.length > 0 ? source[0].value : null;
const version = source.flatMap(c => c.children.filter(n => n.tag === "VERS" /* Tag.Version */));
const versionOpt = version.length > 0 ? version[0].value : null;
return { sourceEncoding: charOpt, sourceProvider: sourceOpt, sourceProviderVersion: versionOpt, fileHasBOM: hasBOM };
};
exports.getFileMetadata = getFileMetadata;
/**
* Detects the file charset using a set of heuristics. Has proven to work great in practice.
* If you encounter a file for which this procedure doesn't work as intended please do open an issue
* at: https://github.com/arbre-app/read-gedcom/issues.
* @param buffer The content of the file
*/
const detectCharset = (buffer) => {
// eslint-disable-next-line
const { sourceEncoding, sourceProvider, sourceProviderVersion, fileHasBOM } = (0, exports.getFileMetadata)(buffer);
// Estimate an encoding without knowing the provider
function estimateEncoding() {
if (sourceEncoding === "UTF-8" /* ValueCharacterEncoding.Utf8 */) {
return "UTF-8" /* FileEncoding.Utf8 */;
}
else if (sourceEncoding === "ANSEL" /* ValueCharacterEncoding.Ansel */) {
return "ANSEL" /* FileEncoding.Ansel */;
}
else if (sourceEncoding === "ASCII" /* ValueCharacterEncoding.Ascii */) {
return "Cp1252" /* FileEncoding.Cp1252 */;
}
else if (sourceEncoding === "ANSI" /* ValueCharacterEncoding.Ansi */) {
return "Cp1252" /* FileEncoding.Cp1252 */;
}
else if (sourceEncoding === "UNICODE" /* ValueCharacterEncoding.Unicode */) {
return "UTF-16be" /* FileEncoding.Utf16be */; // RFC 2781
}
else if (sourceEncoding === 'WINDOWS' || sourceEncoding === 'IBM WINDOWS') {
return "Cp1252" /* FileEncoding.Cp1252 */;
}
else if (sourceEncoding === 'MACINTOSH') {
return "Macintosh" /* FileEncoding.Macintosh */;
}
else if (sourceEncoding === 'IBMPC') {
return "Cp850" /* FileEncoding.Cp850 */;
}
else if (sourceEncoding === 'MSDOS') {
return "Cp850" /* FileEncoding.Cp850 */;
}
else if (sourceEncoding === 'UNIX') {
return "Cp1252" /* FileEncoding.Cp1252 */;
}
else if (sourceEncoding === 'UTF8') { // Spelling mistake
return "UTF-8" /* FileEncoding.Utf8 */;
}
else if (sourceEncoding === 'windows-1250') { // Our best guess (Rodokmen Pro)
return "Cp1252" /* FileEncoding.Cp1252 */;
}
else { // Unknown encoding
return "UTF-8" /* FileEncoding.Utf8 */; // Defaults to UTF-8
}
}
if (fileHasBOM) { // Short-circuit: must be one of UTF-{8,16,32}
return "UTF-8" /* FileEncoding.Utf8 */;
}
if (sourceProvider === 'GeneWeb') { // Geneweb
if (sourceEncoding === "ASCII" /* ValueCharacterEncoding.Ascii */) {
return "Cp1252" /* FileEncoding.Cp1252 */;
}
else if (sourceEncoding === "UTF-8" /* ValueCharacterEncoding.Utf8 */) {
return "UTF-8" /* FileEncoding.Utf8 */;
}
else {
return estimateEncoding();
}
}
else if (sourceProvider != null && sourceProvider.startsWith('HEREDIS')) { // Heredis
if (sourceEncoding === "ANSI" /* ValueCharacterEncoding.Ansi */) {
return "Cp1252" /* FileEncoding.Cp1252 */;
}
else {
return estimateEncoding();
}
}
else if (sourceProvider === 'GENEATIQUE') { // Généatique
if (sourceEncoding === "ANSEL" /* ValueCharacterEncoding.Ansel */) {
return "ANSEL" /* FileEncoding.Ansel */;
}
else {
return estimateEncoding();
}
}
else if (sourceProvider === 'Gramps') { // Gramps
if (sourceEncoding === "UTF-8" /* ValueCharacterEncoding.Utf8 */) {
return "UTF-8" /* FileEncoding.Utf8 */;
}
else {
return estimateEncoding();
}
}
else { // Unknown provider
return estimateEncoding();
}
};
exports.detectCharset = detectCharset;
//# sourceMappingURL=decoder.js.map
@@ -0,0 +1 @@
{"version":3,"file":"decoder.js","sourceRoot":"","sources":["../../../src/parse/decoder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
/**
* The signature of a decoder.
*/
export declare type FileDecoder = (buffer: ArrayBuffer, progressCallback?: (bytesRead: number) => void, strict?: boolean) => string;
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=FileDecoder.js.map
@@ -0,0 +1 @@
{"version":3,"file":"FileDecoder.js","sourceRoot":"","sources":["../../../../src/parse/decoding/FileDecoder.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
import { FileDecoder } from './FileDecoder';
export declare const decodeAnsel: FileDecoder;
@@ -0,0 +1,69 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.decodeAnsel = void 0;
const error_1 = require("../error");
const common_1 = require("./common");
const ANSEL_KEYS_1 = '8d8ea1a2a3a4a5a6a7a8a9aaabacadaeb0b1b2b3b4b5b6b7b8b9babcbdc0c1c2c3c4c5c6cfe0e1e2e3e4e5e6e7e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfe818889929394c7c8e8bebfcdce';
const ANSEL_VALUES_1 = '\u200d\u200c\u0141\xd8\xd0\xde\xc6\u0152\u02b9\xb7\u266d\xae\xb1\u01a0\u01af\u02be\xb0\u0142\xf8\u0111\xfe\xe6\u0153\u02ba\u0131\xa3\xf0\u01a1\u01b0\xb0\u2113\u2117\xa9\u266f\xbf\xa1\xdf\u0309\u0300\u0301\u0302\u0303\u0304\u0306\u0307\u030c\u030a\ufe20\ufe21\u0315\u030b\u0310\u0327\u0328\u0323\u0324\u0325\u0333\u0332\u0326\u031c\u032e\ufe22\ufe23\u0313\xfc\x98\x9c\'\u201c\u201d\xdf\u20ac\u0308\u25af\u25aeeo';
const ANSEL_KEYS_2 = 'e020e041e045e049e04fe055e059e061e065e069e06fe075e079e120e141e145e149e14fe155e157e159e161e165e169e16fe175e177e179e220e241e243e245e247e249e24be24ce24de24ee24fe250e252e253e255e257e259e25ae261e263e265e267e269e26be26ce26de26ee26fe270e272e273e275e277e279e27ae2a5e2b5e320e341e343e345e347e348e349e34ae34fe353e355e357e359e35ae361e363e365e367e368e369e36ae36fe373e375e377e379e37ae420e441e445e449e44ee44fe455e456e459e461e465e469e46ee46fe475e476e479e520e541e545e547e549e54fe555e561e565e567e569e56fe575e5a5e5b5e620e641e645e647e649e64fe655e661e665e667e669e66fe675e720e742e743e744e745e746e747e748e749e74de74ee750e752e753e754e757e758e759e75ae762e763e764e765e766e767e768e76de76ee770e772e773e774e777e778e779e77ae820e841e845e848e849e84fe855e857e858e859e861e865e868e869e86fe874e875e877e878e879e920e941e943e944e945e947e949e94be94ce94ee94fe952e953e954e955e95ae961e963e964e965e967e969e96ae96be96ce96ee96fe972e973e974e975e97aea20ea41ea61ea75ea77ea79eaaded20ee20ee4fee55ee6fee75f020f043f044f047f048f04bf04cf04ef052f053f054f063f064f067f068f06bf06cf06ef072f073f074f120f141f145f149f14ff155f161f165f169f16ff175f241f242f244f245f248f249f24bf24cf24df24ef24ff252f253f254f255f256f257f259f25af261f262f264f265f268f269f26bf26cf26df26ef26ff272f273f274f275f276f277f279f27af355f375f441f461f520f948f968fc20fc41fc43fc45fc4bfc4cfc4ffc51fc54fc56fc61fc63fc65fc6bfc6cfc6ffc71fc74fc76d741d742d743d744d745d746d747d748d749d74ad74bd74cd74dd74ed74fd750d751d752d753d754d755d756d757d758d761d762d763d764d765d766d767d768d769d76ad76bd76cd76dd76ed76fd770d771d772d773d774d775d776d777d778d779d824d841d842d843d844d845d846d847d848d849d84bd84cd84dd84ed84fd850d851d852d853d854d855d856d857d858d85ad861d862d863d864d865d866d867d868d869d86bd86cd86dd86ed86fd870d871d872d873d874d875d876d877d878d87ad920d921d922d923d924d925d926d927d928d929d92ad92bd92cd92dd92ed92fd930d931d932d933d941d942d943d944d945d946d947d948d949d94ad94cd94dd94ed94fd950d951d952d953d954d955d956d957d958d959d95ad961d962d963d964d965d966d967d968d969d96ad96bd96cd96dd96ed96fd970d971d972d973d974d975d976d977d979d97ad97bd97c';
const ANSEL_VALUES_2 = '\u02c0\u1ea2\u1eba\u1ec8\u1ece\u1ee6\u1ef6\u1ea3\u1ebb\u1ec9\u1ecf\u1ee7\u1ef7\u02cb\xc0\xc8\xcc\xd2\xd9\u1e80\u1ef2\xe0\xe8\xec\xf2\xf9\u1e81\u1ef3\u02ca\xc1\u0106\xc9\u01f4\xcd\u1e30\u0139\u1e3e\u0143\xd3\u1e54\u0154\u015a\xda\u1e82\xdd\u0179\xe1\u0107\xe9\u01f5\xed\u1e31\u013a\u1e3f\u0144\xf3\u1e55\u0155\u015b\xfa\u1e83\xfd\u017a\u01fc\u01fd\u02c6\xc2\u0108\xca\u011c\u0124\xce\u0134\xd4\u015c\xdb\u0174\u0176\u1e90\xe2\u0109\xea\u011d\u0125\xee\u0135\xf4\u015d\xfb\u0175\u0177\u1e91\u02dc\xc3\u1ebc\u0128\xd1\xd5\u0168\u1e7c\u1ef8\xe3\u1ebd\u0129\xf1\xf5\u0169\u1e7d\u1ef9\u02c9\u0100\u0112\u1e20\u012a\u014c\u016a\u0101\u0113\u1e21\u012b\u014d\u016b\u01e2\u01e3\u02d8\u0102\u0114\u011e\u012c\u014e\u016c\u0103\u0115\u011f\u012d\u014f\u016d\u02d9\u1e02\u010a\u1e0a\u0116\u1e1e\u0120\u1e22\u0130\u1e40\u1e44\u1e56\u1e58\u1e60\u1e6a\u1e86\u1e8a\u1e8e\u017b\u1e03\u010b\u1e0b\u0117\u1e1f\u0121\u1e23\u1e41\u1e45\u1e57\u1e59\u1e61\u1e6b\u1e87\u1e8b\u1e8f\u017c\xa8\xc4\xcb\u1e26\xcf\xd6\xdc\u1e84\u1e8c\u0178\xe4\xeb\u1e27\xef\xf6\u1e97\xfc\u1e85\u1e8d\xff\u02c7\u01cd\u010c\u010e\u011a\u01e6\u01cf\u01e8\u013d\u0147\u01d1\u0158\u0160\u0164\u01d3\u017d\u01ce\u010d\u010f\u011b\u01e7\u01d0\u01f0\u01e9\u013e\u0148\u01d2\u0159\u0161\u0165\u01d4\u017e\u02da\xc5\xe5\u016f\u1e98\u1e99\u016e\u02bc\u02dd\u0150\u0170\u0151\u0171\xb8\xc7\u1e10\u0122\u1e28\u0136\u013b\u0145\u0156\u015e\u0162\xe7\u1e11\u0123\u1e29\u0137\u013c\u0146\u0157\u015f\u0163\u02db\u0104\u0118\u012e\u01ea\u0172\u0105\u0119\u012f\u01eb\u0173\u1ea0\u1e04\u1e0c\u1eb8\u1e24\u1eca\u1e32\u1e36\u1e42\u1e46\u1ecc\u1e5a\u1e62\u1e6c\u1ee4\u1e7e\u1e88\u1ef4\u1e92\u1ea1\u1e05\u1e0d\u1eb9\u1e25\u1ecb\u1e33\u1e37\u1e43\u1e47\u1ecd\u1e5b\u1e63\u1e6d\u1ee5\u1e7f\u1e89\u1ef5\u1e93\u1e72\u1e73\u1e00\u1e01\u2017\u1e2a\u1e2b\u0338\u023a\u023b\u0246\ua742\u0141\xd8\ua758\u023e\ua75e\u2c65\u023c\u0247\ua743\u0142\xf8\ua759\u2c66\ua75f\u2550\u2551\u2557\u255d\u255a\u2554\u2563\u2569\u2560\u2566\u256c\u2562\u2567\u255f\u2564\u2561\u2568\u255e\u2565\u256a\u2591\u2592\u2593\u2588\u2500\u2502\u2510\u2518\u2514\u250c\u2524\u2534\u251c\u252c\u253c\u2555\u255b\u2558\u2552\u2556\u255c\u2559\u2553\u256b\u258c\u2580\u2590\u2584\u25aa\u03c2\u0391\u0392\u03a5\u0394\u0395\u03a6\u0393\u03a8\u0399\u039a\u039b\u039c\u039d\u039f\u03a0\u03a7\u03a1\u03a3\u03a4\u03a9\u0398\u0397\u039e\u0396\u03b1\u03b2\u03c5\u03b4\u03b5\u03c6\u03b3\u03c8\u03b9\u03ba\u03bb\u03bc\u03bd\u03bf\u03c0\u03c7\u03c1\u03c3\u03c4\u03c9\u03b8\u03b7\u03be\u03b6\u0e3f\xa2\xa5\u20a7\u0192\xa4\u20a4\u20a0\u20a1\u20a2\u20a3\u20a5\u20a6\u20a8\u20a9\u20aa\u20ac\xb9\xb2\xb3\xaa\xba\xab\xbb\xa6\xb6\xa7\u2310\u2020\u2021\u2122\ufb01\ufb02\u2039\u203a\u2030\u2026\u201c\u201d\u201a\u201e\u2022\u2013\xa0\xb5\xbd\xbc\xbe\u221e\u2205\u2208\u2229\xac\u2261\xd7\u2265\u2264\xf7\u2248\u22c5\u2320\u2321\u221a\u2044\u2018\u2019\u2014\xad\u20ad\u20ae\u20af\u20ab';
const REPLACEMENT_CHARACTER = '\ufffd';
const decodeAnsel = (buffer, progressCallback, strict) => {
if (progressCallback) {
progressCallback(0);
}
const createTable = (keys, keysStride, values) => {
const map = new Map();
for (let i = 0; i < keys.length; i++) {
map.set(parseInt(keys.substring(i * keysStride, (i + 1) * keysStride), 16), values.charCodeAt(i));
}
return map;
};
const table1 = createTable(ANSEL_KEYS_1, 2, ANSEL_VALUES_1), table2 = createTable(ANSEL_KEYS_2, 4, ANSEL_VALUES_2);
const byteBuffer = new Uint8Array(buffer);
const output = [];
let i = 0;
let pending = byteBuffer[i];
i++;
while (pending !== undefined) {
const b = pending;
pending = byteBuffer[i];
i++;
if (b < 128) { // Unchanged ASCII
output.push(String.fromCharCode(b));
}
else if (pending !== undefined && ((b >= 0xE0 && b <= 0xFF) || (b >= 0xD7 && b <= 0xD9))) {
// Two bytes
const code = b * 256 + pending;
const u = table2.get(code);
if (u !== undefined) {
pending = byteBuffer[i];
i++;
output.push(String.fromCharCode(u));
}
else if (!strict) {
pending = byteBuffer[i];
i++;
output.push(REPLACEMENT_CHARACTER);
}
else {
throw new error_1.ErrorGedcomDecoding(`Illegal ANSEL character code: ${code}`, code);
}
}
else {
// One byte
const u = table1.get(b);
const c = String.fromCharCode(u !== undefined ? u : 0xFFFD);
output.push(c);
}
if (progressCallback && i % common_1.BYTES_INTERVAL === 0) {
progressCallback(i);
}
}
if (progressCallback) {
progressCallback(i);
}
return output.join('');
};
exports.decodeAnsel = decodeAnsel;
//# sourceMappingURL=ansel.js.map
@@ -0,0 +1 @@
{"version":3,"file":"ansel.js","sourceRoot":"","sources":["../../../../src/parse/decoding/ansel.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
/**
* The iteration interval at which the next progress call should be performed.
*/
export declare const BYTES_INTERVAL = 200000;
@@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BYTES_INTERVAL = void 0;
/**
* The iteration interval at which the next progress call should be performed.
*/
exports.BYTES_INTERVAL = 200000;
//# sourceMappingURL=common.js.map
@@ -0,0 +1 @@
{"version":3,"file":"common.js","sourceRoot":"","sources":["../../../../src/parse/decoding/common.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACU,QAAA,cAAc,GAAG,MAAM,CAAC"}
@@ -0,0 +1,2 @@
import { FileDecoder } from './FileDecoder';
export declare const decodeCp1252: FileDecoder;
@@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.decodeCp1252 = void 0;
// https://stackoverflow.com/a/4129920/4413709
const common_1 = require("./common");
const CP1252_TABLE = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u20ac\ufffd\u201a\u0192\u201e\u2026\u2020\u2021\u02c6\u2030\u0160\u2039\u0152\ufffd\u017d\ufffd\ufffd\u2018\u2019\u201c\u201d\u2022\u2013\u2014\u02dc\u2122\u0161\u203a\u0153\ufffd\u017e\u0178\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff';
const decodeCp1252 = (buffer, progressCallback) => {
if (progressCallback) {
progressCallback(0);
}
const byteBuffer = new Uint8Array(buffer);
let outputView = '';
let i = 0;
for (; i < byteBuffer.length; i++) {
outputView += CP1252_TABLE.charAt(byteBuffer[i]);
if (progressCallback && i % common_1.BYTES_INTERVAL === 0) {
progressCallback(i);
}
}
if (progressCallback) {
progressCallback(i);
}
return outputView;
};
exports.decodeCp1252 = decodeCp1252;
//# sourceMappingURL=cp1252.js.map
@@ -0,0 +1 @@
{"version":3,"file":"cp1252.js","sourceRoot":"","sources":["../../../../src/parse/decoding/cp1252.ts"],"names":[],"mappings":";;;AAAA,8CAA8C;AAC9C,qCAA0C;AAG1C,MAAM,YAAY,GAAG,iyBAAiyB,CAAC;AAEhzB,MAAM,YAAY,GAAgB,CAAC,MAAM,EAAE,gBAAiB,EAAE,EAAE;IACnE,IAAI,gBAAgB,EAAE;QAClB,gBAAgB,CAAC,CAAC,CAAC,CAAC;KACvB;IAED,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;IAC1C,IAAI,UAAU,GAAG,EAAE,CAAC;IACpB,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QAC/B,UAAU,IAAI,YAAY,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;QAEjD,IAAI,gBAAgB,IAAI,CAAC,GAAG,uBAAc,KAAK,CAAC,EAAE;YAC9C,gBAAgB,CAAC,CAAC,CAAC,CAAC;SACvB;KACJ;IAED,IAAI,gBAAgB,EAAE;QAClB,gBAAgB,CAAC,CAAC,CAAC,CAAC;KACvB;IAED,OAAO,UAAU,CAAC;AACtB,CAAC,CAAC;AArBW,QAAA,YAAY,gBAqBvB"}
@@ -0,0 +1,2 @@
import { FileDecoder } from './FileDecoder';
export declare const decodeCp850: FileDecoder;
@@ -0,0 +1,27 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.decodeCp850 = void 0;
// Generated according to https://en.wikipedia.org/wiki/Code_page_437
const common_1 = require("./common");
const CP850_TABLE = '\xc7\xfc\xe9\xe2\xe4\xe0\xe5\xe7\xea\xeb\xe8\xef\xee\xec\xc4\xc5\xc9\xe6\xc6\xf4\xf6\xf2\xfb\xf9\xff\xd6\xdc\xf8\xa3\xd8\xd7\u0192\xe1\xed\xf3\xfa\xf1\xd1\xaa\xba\xbf\xae\xac\xbd\xbc\xa1\xab\xbb\u2591\u2592\u2593\u2502\u2524\xc1\xc2\xc0\xa9\u2563\u2551\u2557\u255d\xa2\xa5\u2510\u2514\u2534\u252c\u251c\u2500\u253c\xe3\xc3\u255a\u2554\u2569\u2566\u2560\u2550\u256c\xa4\xf0\xd0\xca\xcb\xc8\u0131\xcd\xce\xcf\u2518\u250c\u2588\u2584\xa6\xcc\u2580\xd3\xdf\xd4\xd2\xf5\xd5\xb5\xfe\xde\xda\xdb\xd9\xfd\xdd\xaf\xb4\xad\xb1\u2017\xbe\xb6\xa7\xf7\xb8\xb0\xa8\xb7\xb9\xb3\xb2';
const decodeCp850 = (buffer, progressCallback) => {
if (progressCallback) {
progressCallback(0);
}
const byteBuffer = new Uint8Array(buffer);
let outputView = '';
let i = 0;
for (; i < byteBuffer.length; i++) {
const code = byteBuffer[i];
outputView += code < 128 ? String.fromCharCode(code) : CP850_TABLE.charAt(code - 128);
if (progressCallback && i % common_1.BYTES_INTERVAL === 0) {
progressCallback(i);
}
}
if (progressCallback) {
progressCallback(i);
}
return outputView;
};
exports.decodeCp850 = decodeCp850;
//# sourceMappingURL=cp850.js.map
@@ -0,0 +1 @@
{"version":3,"file":"cp850.js","sourceRoot":"","sources":["../../../../src/parse/decoding/cp850.ts"],"names":[],"mappings":";;;AAAA,qEAAqE;AACrE,qCAA0C;AAG1C,MAAM,WAAW,GAAG,wjBAAwjB,CAAC;AAEtkB,MAAM,WAAW,GAAgB,CAAC,MAAM,EAAE,gBAAiB,EAAE,EAAE;IAClE,IAAI,gBAAgB,EAAE;QAClB,gBAAgB,CAAC,CAAC,CAAC,CAAC;KACvB;IAED,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;IAC1C,IAAI,UAAU,GAAG,EAAE,CAAC;IACpB,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QAC/B,MAAM,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;QAC3B,UAAU,IAAI,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC;QAEtF,IAAI,gBAAgB,IAAI,CAAC,GAAG,uBAAc,KAAK,CAAC,EAAE;YAC9C,gBAAgB,CAAC,CAAC,CAAC,CAAC;SACvB;KACJ;IAED,IAAI,gBAAgB,EAAE;QAClB,gBAAgB,CAAC,CAAC,CAAC,CAAC;KACvB;IAED,OAAO,UAAU,CAAC;AACtB,CAAC,CAAC;AAtBW,QAAA,WAAW,eAsBtB"}
@@ -0,0 +1,5 @@
export { decodeAnsel } from './ansel';
export { decodeCp1252 } from './cp1252';
export { decodeUtf, decodeUtfBOM, decodeUtf8, decodeUtf16le, decodeUtf16be, BOM_UTF8, BOM_UTF16_BE, BOM_UTF16_LE, BOM_UTF32_BE, BOM_UTF32_LE } from './utf';
export { decodeMacintosh } from './macintosh';
export { decodeCp850 } from './cp850';
@@ -0,0 +1,23 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.decodeCp850 = exports.decodeMacintosh = exports.BOM_UTF32_LE = exports.BOM_UTF32_BE = exports.BOM_UTF16_LE = exports.BOM_UTF16_BE = exports.BOM_UTF8 = exports.decodeUtf16be = exports.decodeUtf16le = exports.decodeUtf8 = exports.decodeUtfBOM = exports.decodeUtf = exports.decodeCp1252 = exports.decodeAnsel = void 0;
var ansel_1 = require("./ansel");
Object.defineProperty(exports, "decodeAnsel", { enumerable: true, get: function () { return ansel_1.decodeAnsel; } });
var cp1252_1 = require("./cp1252");
Object.defineProperty(exports, "decodeCp1252", { enumerable: true, get: function () { return cp1252_1.decodeCp1252; } });
var utf_1 = require("./utf");
Object.defineProperty(exports, "decodeUtf", { enumerable: true, get: function () { return utf_1.decodeUtf; } });
Object.defineProperty(exports, "decodeUtfBOM", { enumerable: true, get: function () { return utf_1.decodeUtfBOM; } });
Object.defineProperty(exports, "decodeUtf8", { enumerable: true, get: function () { return utf_1.decodeUtf8; } });
Object.defineProperty(exports, "decodeUtf16le", { enumerable: true, get: function () { return utf_1.decodeUtf16le; } });
Object.defineProperty(exports, "decodeUtf16be", { enumerable: true, get: function () { return utf_1.decodeUtf16be; } });
Object.defineProperty(exports, "BOM_UTF8", { enumerable: true, get: function () { return utf_1.BOM_UTF8; } });
Object.defineProperty(exports, "BOM_UTF16_BE", { enumerable: true, get: function () { return utf_1.BOM_UTF16_BE; } });
Object.defineProperty(exports, "BOM_UTF16_LE", { enumerable: true, get: function () { return utf_1.BOM_UTF16_LE; } });
Object.defineProperty(exports, "BOM_UTF32_BE", { enumerable: true, get: function () { return utf_1.BOM_UTF32_BE; } });
Object.defineProperty(exports, "BOM_UTF32_LE", { enumerable: true, get: function () { return utf_1.BOM_UTF32_LE; } });
var macintosh_1 = require("./macintosh");
Object.defineProperty(exports, "decodeMacintosh", { enumerable: true, get: function () { return macintosh_1.decodeMacintosh; } });
var cp850_1 = require("./cp850");
Object.defineProperty(exports, "decodeCp850", { enumerable: true, get: function () { return cp850_1.decodeCp850; } });
//# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/parse/decoding/index.ts"],"names":[],"mappings":";;;AAAA,iCAAsC;AAA7B,oGAAA,WAAW,OAAA;AACpB,mCAAwC;AAA/B,sGAAA,YAAY,OAAA;AACrB,6BAA4J;AAAnJ,gGAAA,SAAS,OAAA;AAAE,mGAAA,YAAY,OAAA;AAAE,iGAAA,UAAU,OAAA;AAAE,oGAAA,aAAa,OAAA;AAAE,oGAAA,aAAa,OAAA;AAAE,+FAAA,QAAQ,OAAA;AAAE,mGAAA,YAAY,OAAA;AAAE,mGAAA,YAAY,OAAA;AAAE,mGAAA,YAAY,OAAA;AAAE,mGAAA,YAAY,OAAA;AAC5I,yCAA8C;AAArC,4GAAA,eAAe,OAAA;AACxB,iCAAsC;AAA7B,oGAAA,WAAW,OAAA"}
@@ -0,0 +1,2 @@
import { FileDecoder } from './FileDecoder';
export declare const decodeMacintosh: FileDecoder;
@@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.decodeMacintosh = void 0;
// Generated according to https://en.wikipedia.org/wiki/Mac_OS_Roman
const common_1 = require("./common");
const MACINTOSH_TABLE = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\u2318\u2713\u25c6\uf8ff\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\xc4\xc5\xc7\xc9\xd1\xd6\xdc\xe1\xe0\xe2\xe4\xe3\xe5\xe7\xe9\xe8\xea\xeb\xed\xec\xee\xef\xf1\xf3\xf2\xf4\xf6\xf5\xfa\xf9\xfb\xfc\u2020\xb0\xa2\xa3\xa7\u2022\xb6\xdf\xae\xa9\u2122\xb4\xa8\u2260\xc6\xd8\u221e\xb1\u2264\u2265\xa5\xb5\u2202\u2211\u220f\u03c0\u222b\xaa\xba\u03a9\xe6\xf8\xbf\xa1\xac\u221a\u0192\u2248\u2206\xab\xbb\u2026\xa0\xc0\xc3\xd5\u0152\u0153\u2013\u2014\u201c\u201d\u2018\u2019\xf7\u25ca\xff\u0178\u2044\u20ac\u2039\u203a\ufb01\ufb02\u2021\xb7\u201a\u201e\u2030\xc2\xca\xc1\xcb\xc8\xcd\xce\xcf\xcc\xd3\xd4\uf8ff\xd2\xda\xdb\xd9\u0131\u02c6\u02dc\xaf\u02d8\u02d9\u02da\xb8\u02dd\u02db\u02c7';
const decodeMacintosh = (buffer, progressCallback) => {
if (progressCallback) {
progressCallback(0);
}
const byteBuffer = new Uint8Array(buffer);
let outputView = '';
let i = 0;
for (; i < byteBuffer.length; i++) {
outputView += MACINTOSH_TABLE.charAt(byteBuffer[i]);
if (progressCallback && i % common_1.BYTES_INTERVAL === 0) {
progressCallback(0);
}
}
if (progressCallback) {
progressCallback(i);
}
return outputView;
};
exports.decodeMacintosh = decodeMacintosh;
//# sourceMappingURL=macintosh.js.map
@@ -0,0 +1 @@
{"version":3,"file":"macintosh.js","sourceRoot":"","sources":["../../../../src/parse/decoding/macintosh.ts"],"names":[],"mappings":";;;AAAA,oEAAoE;AACpE,qCAA0C;AAG1C,MAAM,eAAe,GAAG,y0BAAy0B,CAAC;AAE31B,MAAM,eAAe,GAAgB,CAAC,MAAM,EAAE,gBAAiB,EAAE,EAAE;IACtE,IAAI,gBAAgB,EAAE;QAClB,gBAAgB,CAAC,CAAC,CAAC,CAAC;KACvB;IAED,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;IAC1C,IAAI,UAAU,GAAG,EAAE,CAAC;IACpB,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QAC/B,UAAU,IAAI,eAAe,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;QAEpD,IAAI,gBAAgB,IAAI,CAAC,GAAG,uBAAc,KAAK,CAAC,EAAE;YAC9C,gBAAgB,CAAC,CAAC,CAAC,CAAC;SACvB;KACJ;IAED,IAAI,gBAAgB,EAAE;QAClB,gBAAgB,CAAC,CAAC,CAAC,CAAC;KACvB;IAED,OAAO,UAAU,CAAC;AACtB,CAAC,CAAC;AArBW,QAAA,eAAe,mBAqB1B"}
@@ -0,0 +1,17 @@
import { FileDecoder } from './FileDecoder';
export declare const BOM_UTF8: number[];
export declare const BOM_UTF16_BE: number[];
export declare const BOM_UTF16_LE: number[];
export declare const BOM_UTF32_BE: number[];
export declare const BOM_UTF32_LE: number[];
export declare const DECODE_UTF8 = "utf-8";
export declare const DECODE_UTF16_BE = "utf-16be";
export declare const DECODE_UTF16_LE = "utf-16le";
export declare const decodeUtf: FileDecoder;
export declare const decodeUtf8: FileDecoder;
export declare const decodeUtf16be: FileDecoder;
export declare const decodeUtf16le: FileDecoder;
export declare const decodeUtfBOM: (buffer: ArrayBuffer, progressCallback?: ((bytesRead: number) => void) | undefined) => {
output: string;
bomCharset: string | null;
};
@@ -0,0 +1,114 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.decodeUtfBOM = exports.decodeUtf16le = exports.decodeUtf16be = exports.decodeUtf8 = exports.decodeUtf = exports.DECODE_UTF16_LE = exports.DECODE_UTF16_BE = exports.DECODE_UTF8 = exports.BOM_UTF32_LE = exports.BOM_UTF32_BE = exports.BOM_UTF16_LE = exports.BOM_UTF16_BE = exports.BOM_UTF8 = void 0;
const error_1 = require("../error");
const common_1 = require("./common");
exports.BOM_UTF8 = [0xef, 0xbb, 0xbf];
exports.BOM_UTF16_BE = [0xfe, 0xff];
exports.BOM_UTF16_LE = exports.BOM_UTF16_BE.slice().reverse();
// These are not part of the specification
exports.BOM_UTF32_BE = [0x00, 0x00, 0xfe, 0xff];
exports.BOM_UTF32_LE = exports.BOM_UTF32_BE.slice().reverse();
exports.DECODE_UTF8 = 'utf-8';
exports.DECODE_UTF16_BE = 'utf-16be';
exports.DECODE_UTF16_LE = 'utf-16le';
const decodeUtf = (buffer, progressCallback) => {
const { output } = (0, exports.decodeUtfBOM)(buffer, progressCallback);
return output;
};
exports.decodeUtf = decodeUtf;
const decodeUtf8 = (buffer, progressCallback) => {
if (progressCallback) {
progressCallback(0);
}
let outputView = '';
const byteBuffer = new Uint8Array(buffer);
let nIdx = 0;
for (let nPart, nLen = byteBuffer.length; nIdx < nLen; nIdx++) {
nPart = byteBuffer[nIdx];
outputView += String.fromCharCode(nPart > 251 && nPart < 254 && nIdx + 5 < nLen /* six bytes */
/* (nPart - 252 << 30) may be not so safe in ECMAScript! So...: */
? (nPart - 252) * 1073741824 + (byteBuffer[++nIdx] - 128 << 24) + (byteBuffer[++nIdx] - 128 << 18) + (byteBuffer[++nIdx] - 128 << 12) + (byteBuffer[++nIdx] - 128 << 6) + byteBuffer[++nIdx] - 128
: nPart > 247 && nPart < 252 && nIdx + 4 < nLen /* five bytes */
? (nPart - 248 << 24) + (byteBuffer[++nIdx] - 128 << 18) + (byteBuffer[++nIdx] - 128 << 12) + (byteBuffer[++nIdx] - 128 << 6) + byteBuffer[++nIdx] - 128
: nPart > 239 && nPart < 248 && nIdx + 3 < nLen /* four bytes */
? (nPart - 240 << 18) + (byteBuffer[++nIdx] - 128 << 12) + (byteBuffer[++nIdx] - 128 << 6) + byteBuffer[++nIdx] - 128
: nPart > 223 && nPart < 240 && nIdx + 2 < nLen /* three bytes */
? (nPart - 224 << 12) + (byteBuffer[++nIdx] - 128 << 6) + byteBuffer[++nIdx] - 128
: nPart > 191 && nPart < 224 && nIdx + 1 < nLen /* two bytes */
? (nPart - 192 << 6) + byteBuffer[++nIdx] - 128
: /* nPart < 127 ? */ /* one byte */ nPart);
if (progressCallback && nIdx % common_1.BYTES_INTERVAL === 0) {
progressCallback(nIdx);
}
}
if (progressCallback) {
progressCallback(nIdx);
}
return outputView;
};
exports.decodeUtf8 = decodeUtf8;
const decodeUtf16 = (buffer, isBe, progressCallback) => {
if (progressCallback) {
progressCallback(0);
}
let outputView = '';
const byteBuffer = new Uint8Array(buffer);
for (let i = 0; i < byteBuffer.length; i += 2) {
const a = byteBuffer[i], b = byteBuffer[i + 1];
const code = isBe ? a * 16 + b : b * 16 + a;
outputView += String.fromCharCode(code);
if (progressCallback && ((i + 1) / 2) % common_1.BYTES_INTERVAL === 0) {
progressCallback(i);
}
}
return outputView;
};
const decodeUtf16be = (buffer, progressCallback) => decodeUtf16(buffer, true, progressCallback);
exports.decodeUtf16be = decodeUtf16be;
const decodeUtf16le = (buffer, progressCallback) => decodeUtf16(buffer, false, progressCallback);
exports.decodeUtf16le = decodeUtf16le;
const decodeUtfBOM = (buffer, progressCallback) => {
if (progressCallback) {
progressCallback(0);
}
const byteBuffer = new Uint8Array(buffer);
const startsWith = (bom) => {
if (byteBuffer.length < bom.length) {
return false;
}
for (let i = 0; i < bom.length; i++) {
if (byteBuffer[i] !== bom[i]) {
return false;
}
}
return true;
};
const boms = [[exports.DECODE_UTF8, exports.BOM_UTF8], [exports.DECODE_UTF16_BE, exports.BOM_UTF16_BE], [exports.DECODE_UTF16_LE, exports.BOM_UTF16_LE]];
const optional = boms.map(([charset, bom]) => ({ charset, bom })).find(({ bom }) => startsWith(bom));
if ([exports.BOM_UTF32_BE, exports.BOM_UTF32_LE].some(bom => startsWith(bom))) {
throw new error_1.ErrorUnsupportedCharset(`Unsupported charset detected from BOM: 'utf-32'`, 'utf-32');
}
const bomCharset = optional !== undefined ? optional.charset : null;
const byteBufferWithoutBOM = optional !== undefined ? byteBuffer.slice(optional.bom.length) : byteBuffer;
const charset = bomCharset !== null ? bomCharset : exports.DECODE_UTF8; // No BOM = defaults to UTF-8
let output;
if (charset === exports.DECODE_UTF8) {
output = (0, exports.decodeUtf8)(byteBufferWithoutBOM);
}
else if (charset === exports.DECODE_UTF16_BE) {
output = (0, exports.decodeUtf16be)(byteBufferWithoutBOM);
}
else if (charset === exports.DECODE_UTF16_LE) {
output = (0, exports.decodeUtf16le)(byteBufferWithoutBOM);
}
else {
throw new Error();
}
if (progressCallback) {
progressCallback(byteBuffer.length);
}
return { output, bomCharset };
};
exports.decodeUtfBOM = decodeUtfBOM;
//# sourceMappingURL=utf.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,102 @@
/**
* The base type for all Gedcom related errors. All errors are currently also instances of {@link ErrorParse}.
*/
export declare abstract class ErrorGedcomBase extends Error {
protected constructor(message?: string);
}
/**
* The base class of all parsing errors.
*/
export declare class ErrorParse extends ErrorGedcomBase {
readonly message: string;
constructor(message: string);
}
/**
* Thrown if it is unlikely a Gedcom file, for instance if a completely unrelated file was passed.
*/
export declare class ErrorInvalidFileType extends ErrorParse {
}
/**
* Thrown on likely Gedcom files if there was an error during the decoding of the characters.
* Such an error can be muted by passing <code>false</code> to the <code>strict</code> parameter of a decoding method (for example, {@link decodeAnsel}).
*/
export declare class ErrorGedcomDecoding extends ErrorParse {
readonly illegalCode: number;
constructor(message: string, illegalCode: number);
}
/**
* Thrown on likely Gedcom file in rare occasions if the charset was detected but is not supported.
* An example would be UTF-32.
*/
export declare class ErrorUnsupportedCharset extends ErrorParse {
readonly charset: string;
constructor(message: string, charset: string);
}
/**
* Thrown on likely Gedcom files if a line could not be tokenized properly.
* This is perhaps the most common error in practice.
*/
export declare class ErrorTokenization extends ErrorParse {
readonly lineNumber: number;
readonly line: string;
constructor(message: string, lineNumber: number, line: string);
}
/**
* The base class of all tree structuring errors.
* Such errors can be thrown only after the tokenization phase has completed successfully.
*/
export declare class ErrorTreeSyntax extends ErrorParse {
readonly lineNumber: number;
constructor(message: string, lineNumber: number);
}
/**
* Thrown if a line is incorrectly nested.
*/
export declare class ErrorInvalidNesting extends ErrorTreeSyntax {
readonly lineNumber: number;
readonly currentLevel: number;
readonly level: number;
constructor(message: string, lineNumber: number, currentLevel: number, level: number);
}
/**
* Thrown if a concatenation or a continuation line is incorrectly used.
*/
export declare class ErrorInvalidConcatenation extends ErrorTreeSyntax {
readonly lineNumber: number;
readonly kind: string;
constructor(message: string, lineNumber: number, kind: string);
}
/**
* Thrown if a record appears at a position other than the top-most level.
*/
export declare class ErrorInvalidRecordDefinition extends ErrorTreeSyntax {
constructor(message: string, lineNumber: number);
}
/**
* Thrown if the file does not start with a header or does not end with a trailer.
*/
export declare class ErrorTreeStructure extends ErrorParse {
constructor(message: string);
}
/**
* @deprecated This error cannot occur, an empty tree would throw a {@link ErrorInvalidFileType} instead.
*/
export declare class ErrorEmptyTree extends ErrorTreeStructure {
constructor(message: string);
}
/**
* The base class of all indexing errors.
* Such errors can occur if an inconsistency is discovered while indexing the data.
*/
export declare class ErrorIndexing extends ErrorParse {
constructor(message: string);
}
/**
* Thrown if a duplicate pointer is discovered.
*/
export declare class ErrorDuplicatePointer extends ErrorIndexing {
readonly lineNumber: number;
readonly lineNumberOriginalDefinition: number;
readonly pointer: string;
constructor(message: string, lineNumber: number, lineNumberOriginalDefinition: number, pointer: string);
}
@@ -0,0 +1,169 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ErrorDuplicatePointer = exports.ErrorIndexing = exports.ErrorEmptyTree = exports.ErrorTreeStructure = exports.ErrorInvalidRecordDefinition = exports.ErrorInvalidConcatenation = exports.ErrorInvalidNesting = exports.ErrorTreeSyntax = exports.ErrorTokenization = exports.ErrorUnsupportedCharset = exports.ErrorGedcomDecoding = exports.ErrorInvalidFileType = exports.ErrorParse = exports.ErrorGedcomBase = void 0;
// See https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
const patchPrototype = (instance, target) => {
const proto = target.prototype;
if (Object.setPrototypeOf) {
Object.setPrototypeOf(instance, proto);
}
else {
this.__proto__ = proto; // eslint-disable-line no-proto
}
};
/**
* The base type for all Gedcom related errors. All errors are currently also instances of {@link ErrorParse}.
*/
class ErrorGedcomBase extends Error {
constructor(message) {
super(message);
patchPrototype(this, new.target);
}
}
exports.ErrorGedcomBase = ErrorGedcomBase;
/**
* The base class of all parsing errors.
*/
class ErrorParse extends ErrorGedcomBase {
constructor(message) {
super(message);
this.message = message;
patchPrototype(this, new.target);
}
}
exports.ErrorParse = ErrorParse;
/**
* Thrown if it is unlikely a Gedcom file, for instance if a completely unrelated file was passed.
*/
class ErrorInvalidFileType extends ErrorParse {
}
exports.ErrorInvalidFileType = ErrorInvalidFileType;
/**
* Thrown on likely Gedcom files if there was an error during the decoding of the characters.
* Such an error can be muted by passing <code>false</code> to the <code>strict</code> parameter of a decoding method (for example, {@link decodeAnsel}).
*/
class ErrorGedcomDecoding extends ErrorParse {
constructor(message, illegalCode) {
super(message);
this.illegalCode = illegalCode;
patchPrototype(this, new.target);
}
}
exports.ErrorGedcomDecoding = ErrorGedcomDecoding;
/**
* Thrown on likely Gedcom file in rare occasions if the charset was detected but is not supported.
* An example would be UTF-32.
*/
class ErrorUnsupportedCharset extends ErrorParse {
constructor(message, charset) {
super(message);
this.charset = charset;
patchPrototype(this, new.target);
}
}
exports.ErrorUnsupportedCharset = ErrorUnsupportedCharset;
/**
* Thrown on likely Gedcom files if a line could not be tokenized properly.
* This is perhaps the most common error in practice.
*/
class ErrorTokenization extends ErrorParse {
constructor(message, lineNumber, line) {
super(message);
this.lineNumber = lineNumber;
this.line = line;
patchPrototype(this, new.target);
}
}
exports.ErrorTokenization = ErrorTokenization;
/**
* The base class of all tree structuring errors.
* Such errors can be thrown only after the tokenization phase has completed successfully.
*/
class ErrorTreeSyntax extends ErrorParse {
constructor(message, lineNumber) {
super(message);
this.lineNumber = lineNumber;
patchPrototype(this, new.target);
}
}
exports.ErrorTreeSyntax = ErrorTreeSyntax;
/**
* Thrown if a line is incorrectly nested.
*/
class ErrorInvalidNesting extends ErrorTreeSyntax {
constructor(message, lineNumber, currentLevel, level) {
super(message, lineNumber);
this.lineNumber = lineNumber;
this.currentLevel = currentLevel;
this.level = level;
patchPrototype(this, new.target);
}
}
exports.ErrorInvalidNesting = ErrorInvalidNesting;
/**
* Thrown if a concatenation or a continuation line is incorrectly used.
*/
class ErrorInvalidConcatenation extends ErrorTreeSyntax {
constructor(message, lineNumber, kind) {
super(message, lineNumber);
this.lineNumber = lineNumber;
this.kind = kind;
patchPrototype(this, new.target);
}
}
exports.ErrorInvalidConcatenation = ErrorInvalidConcatenation;
/**
* Thrown if a record appears at a position other than the top-most level.
*/
class ErrorInvalidRecordDefinition extends ErrorTreeSyntax {
constructor(message, lineNumber) {
super(message, lineNumber);
patchPrototype(this, new.target);
}
}
exports.ErrorInvalidRecordDefinition = ErrorInvalidRecordDefinition;
/**
* Thrown if the file does not start with a header or does not end with a trailer.
*/
class ErrorTreeStructure extends ErrorParse {
constructor(message) {
super(message);
patchPrototype(this, new.target);
}
}
exports.ErrorTreeStructure = ErrorTreeStructure;
/**
* @deprecated This error cannot occur, an empty tree would throw a {@link ErrorInvalidFileType} instead.
*/
class ErrorEmptyTree extends ErrorTreeStructure {
constructor(message) {
super(message);
patchPrototype(this, new.target);
}
}
exports.ErrorEmptyTree = ErrorEmptyTree;
/**
* The base class of all indexing errors.
* Such errors can occur if an inconsistency is discovered while indexing the data.
*/
class ErrorIndexing extends ErrorParse {
constructor(message) {
super(message);
patchPrototype(this, new.target);
}
}
exports.ErrorIndexing = ErrorIndexing;
/**
* Thrown if a duplicate pointer is discovered.
*/
class ErrorDuplicatePointer extends ErrorIndexing {
constructor(message, lineNumber, lineNumberOriginalDefinition, pointer) {
super(message);
this.lineNumber = lineNumber;
this.lineNumberOriginalDefinition = lineNumberOriginalDefinition;
this.pointer = pointer;
patchPrototype(this, new.target);
}
}
exports.ErrorDuplicatePointer = ErrorDuplicatePointer;
//# sourceMappingURL=error.js.map
@@ -0,0 +1 @@
{"version":3,"file":"error.js","sourceRoot":"","sources":["../../../src/parse/error.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
/**
* @module Parsing
*/
export * from './value';
export { parseGedcom } from './reader';
/**
* @category Gedcom parser
*/
export { GedcomReadingOptions } from './GedcomReadingOptions';
/**
* @category Gedcom parser
*/
export { GedcomReadingPhase } from './GedcomReadingPhase';
/**
* @category Errors
*/
export { ErrorGedcomBase, ErrorParse, ErrorInvalidFileType, ErrorUnsupportedCharset, ErrorTokenization, ErrorTreeSyntax, ErrorInvalidNesting, ErrorInvalidConcatenation, ErrorInvalidRecordDefinition, ErrorTreeStructure, ErrorEmptyTree, ErrorIndexing, ErrorDuplicatePointer, } from './error';
export { indexTree } from './indexer';
@@ -0,0 +1,48 @@
"use strict";
/**
* @module Parsing
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.indexTree = exports.ErrorDuplicatePointer = exports.ErrorIndexing = exports.ErrorEmptyTree = exports.ErrorTreeStructure = exports.ErrorInvalidRecordDefinition = exports.ErrorInvalidConcatenation = exports.ErrorInvalidNesting = exports.ErrorTreeSyntax = exports.ErrorTokenization = exports.ErrorUnsupportedCharset = exports.ErrorInvalidFileType = exports.ErrorParse = exports.ErrorGedcomBase = exports.GedcomReadingPhase = exports.parseGedcom = void 0;
__exportStar(require("./value"), exports);
var reader_1 = require("./reader");
Object.defineProperty(exports, "parseGedcom", { enumerable: true, get: function () { return reader_1.parseGedcom; } });
/**
* @category Gedcom parser
*/
var GedcomReadingPhase_1 = require("./GedcomReadingPhase");
Object.defineProperty(exports, "GedcomReadingPhase", { enumerable: true, get: function () { return GedcomReadingPhase_1.GedcomReadingPhase; } });
/**
* @category Errors
*/
var error_1 = require("./error");
Object.defineProperty(exports, "ErrorGedcomBase", { enumerable: true, get: function () { return error_1.ErrorGedcomBase; } });
Object.defineProperty(exports, "ErrorParse", { enumerable: true, get: function () { return error_1.ErrorParse; } });
Object.defineProperty(exports, "ErrorInvalidFileType", { enumerable: true, get: function () { return error_1.ErrorInvalidFileType; } });
Object.defineProperty(exports, "ErrorUnsupportedCharset", { enumerable: true, get: function () { return error_1.ErrorUnsupportedCharset; } });
Object.defineProperty(exports, "ErrorTokenization", { enumerable: true, get: function () { return error_1.ErrorTokenization; } });
Object.defineProperty(exports, "ErrorTreeSyntax", { enumerable: true, get: function () { return error_1.ErrorTreeSyntax; } });
Object.defineProperty(exports, "ErrorInvalidNesting", { enumerable: true, get: function () { return error_1.ErrorInvalidNesting; } });
Object.defineProperty(exports, "ErrorInvalidConcatenation", { enumerable: true, get: function () { return error_1.ErrorInvalidConcatenation; } });
Object.defineProperty(exports, "ErrorInvalidRecordDefinition", { enumerable: true, get: function () { return error_1.ErrorInvalidRecordDefinition; } });
Object.defineProperty(exports, "ErrorTreeStructure", { enumerable: true, get: function () { return error_1.ErrorTreeStructure; } });
Object.defineProperty(exports, "ErrorEmptyTree", { enumerable: true, get: function () { return error_1.ErrorEmptyTree; } });
Object.defineProperty(exports, "ErrorIndexing", { enumerable: true, get: function () { return error_1.ErrorIndexing; } });
Object.defineProperty(exports, "ErrorDuplicatePointer", { enumerable: true, get: function () { return error_1.ErrorDuplicatePointer; } });
var indexer_1 = require("./indexer");
Object.defineProperty(exports, "indexTree", { enumerable: true, get: function () { return indexer_1.indexTree; } });
//# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/parse/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;;AAEH,0CAAwB;AACxB,mCAAuC;AAA9B,qGAAA,WAAW,OAAA;AAKpB;;GAEG;AACH,2DAA0D;AAAjD,wHAAA,kBAAkB,OAAA;AAC3B;;GAEG;AACH,iCAciB;AAbb,wGAAA,eAAe,OAAA;AACf,mGAAA,UAAU,OAAA;AACV,6GAAA,oBAAoB,OAAA;AACpB,gHAAA,uBAAuB,OAAA;AACvB,0GAAA,iBAAiB,OAAA;AACjB,wGAAA,eAAe,OAAA;AACf,4GAAA,mBAAmB,OAAA;AACnB,kHAAA,yBAAyB,OAAA;AACzB,qHAAA,4BAA4B,OAAA;AAC5B,2GAAA,kBAAkB,OAAA;AAClB,uGAAA,cAAc,OAAA;AACd,sGAAA,aAAa,OAAA;AACb,8GAAA,qBAAqB,OAAA;AAEzB,qCAAsC;AAA7B,oGAAA,SAAS,OAAA"}
@@ -0,0 +1,11 @@
import { TreeNodeRoot } from '../tree';
/**
* Computes an index for each node in the tree.
* This operation is idempotent: applying several times will not have further effects (but will cost resources as the whole tree will be traversed anyway).
* @param rootNode The root node
* @param noBackwardsReferencesIndex See {@link GedcomReadingOptions.noBackwardsReferencesIndex}
* @param doHideIndex See {@link GedcomReadingOptions.doHideIndex}
* @param progressCallback See {@link GedcomReadingOptions.progressCallback}
* @category Gedcom parser
*/
export declare const indexTree: (rootNode: TreeNodeRoot, noBackwardsReferencesIndex?: boolean, doHideIndex?: boolean, progressCallback?: (() => void) | null) => void;
@@ -0,0 +1,128 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.indexTree = void 0;
const error_1 = require("./error");
const PROGRESS_TRAVERSE_INTERVAL = 50000;
const PROGRESS_ITERATE_INTERVAL = 5000;
/**
* Computes an index for each node in the tree.
* This operation is idempotent: applying several times will not have further effects (but will cost resources as the whole tree will be traversed anyway).
* @param rootNode The root node
* @param noBackwardsReferencesIndex See {@link GedcomReadingOptions.noBackwardsReferencesIndex}
* @param doHideIndex See {@link GedcomReadingOptions.doHideIndex}
* @param progressCallback See {@link GedcomReadingOptions.progressCallback}
* @category Gedcom parser
*/
const indexTree = (rootNode, noBackwardsReferencesIndex = false, doHideIndex = false, progressCallback = null) => {
if (progressCallback) {
progressCallback();
}
let i = 0;
const stack = [[rootNode, 0]];
while (stack.length > 0) {
const [node, childIndex] = stack[stack.length - 1]; // Peek
if (childIndex < node.children.length) {
stack.push([node.children[childIndex], 0]); // Push
}
else {
// eslint-disable-next-line
const [node, _] = stack.pop(); // Pop
if (stack.length > 0) {
stack[stack.length - 1][1]++; // Next child
}
indexNode(node, !doHideIndex); // Index
if (stack.length === 0) {
indexRecords(node); // Index records on root node
}
}
i++;
if (progressCallback && i % PROGRESS_TRAVERSE_INTERVAL === 0) {
progressCallback();
}
}
if (!noBackwardsReferencesIndex) {
indexBackwardsReferences(rootNode, progressCallback);
}
if (progressCallback) {
progressCallback();
}
};
exports.indexTree = indexTree;
const indexNode = (node, enumerable) => {
const byTag = {};
node.children.forEach((child, idx) => {
if (child.tag !== null) {
if (byTag[child.tag] === undefined) {
byTag[child.tag] = [];
}
byTag[child.tag].push(idx);
}
});
Object.defineProperty(node, '_index', {
enumerable,
configurable: true,
writable: true,
});
node._index = { byTag };
};
const indexRecords = (nodeRoot) => {
const byTagPointer = {};
nodeRoot.children.forEach((child, idx) => {
if (child.tag !== null) {
if (child.pointer !== null) {
if (byTagPointer[child.tag] === undefined) {
byTagPointer[child.tag] = {};
}
if (byTagPointer[child.tag][child.pointer] !== undefined) {
throw new error_1.ErrorDuplicatePointer(`Duplicate pointer: ${child.pointer}`, child.indexSource + 1, nodeRoot.children[byTagPointer[child.tag][child.pointer]].indexSource, child.pointer);
}
byTagPointer[child.tag][child.pointer] = idx;
}
}
});
// We assume that the index is defined
nodeRoot._index.byTagPointer = byTagPointer;
};
const indexBackwardsReferences = (rootNode, progressCallback = null) => {
const get = (object, key, def) => {
const value = object[key];
return value != null ? value : def;
};
const index = rootNode._index; // We assume that the index is defined
const families = get(index.byTagPointer, "FAM" /* Tag.Family */, {});
const asSpouse = {}, asChild = {};
Object.values(families).forEach((familyIdx, i) => {
const family = rootNode.children[familyIdx];
const familyIndex = family._index; // Also safe, by assumption
for (const spouseType of ["HUSB" /* Tag.Husband */, "WIFE" /* Tag.Wife */]) {
for (const spouseIdx of get(familyIndex.byTag, spouseType, [])) {
const spouseId = family.children[spouseIdx].value;
if (spouseId !== null) { // We ignore the other possibility (even though it is a hard violation)
if (asSpouse[spouseId] !== undefined) {
asSpouse[spouseId].push(familyIdx);
}
else {
asSpouse[spouseId] = [familyIdx];
}
}
}
}
for (const childIdx of get(familyIndex.byTag, "CHIL" /* Tag.Child */, [])) {
const childId = family.children[childIdx].value;
if (childId !== null) { // ditto
if (asChild[childId] !== undefined) {
asChild[childId].push(familyIdx);
}
else {
asChild[childId] = [familyIdx];
}
}
}
if (progressCallback && i % PROGRESS_ITERATE_INTERVAL === 0) {
progressCallback();
}
});
index.asSpouse = asSpouse;
index.asChild = asChild;
};
//# sourceMappingURL=indexer.js.map
@@ -0,0 +1 @@
{"version":3,"file":"indexer.js","sourceRoot":"","sources":["../../../src/parse/indexer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
import { TreeNodeRoot } from '../tree';
import { GedcomReadingOptions } from './GedcomReadingOptions';
/**
* Reads a Gedcom file and returns it as a tree representation.
* @param buffer The content of the file
* @param options Optional parameters
* @throws ErrorParse If the file cannot be interpreted correctly
* @category Gedcom parser
*/
export declare const parseGedcom: (buffer: ArrayBuffer, options?: GedcomReadingOptions) => TreeNodeRoot;
@@ -0,0 +1,128 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseGedcom = void 0;
const decoder_1 = require("./decoder");
const decoding_1 = require("./decoding");
const error_1 = require("./error");
const indexer_1 = require("./indexer");
const structurer_1 = require("./structurer");
const tokenizer_1 = require("./tokenizer");
/**
* Reads a Gedcom file and returns it as a tree representation.
* @param buffer The content of the file
* @param options Optional parameters
* @throws ErrorParse If the file cannot be interpreted correctly
* @category Gedcom parser
*/
const parseGedcom = (buffer, options = {}) => {
checkMagicHeader(buffer);
const charset = options.forcedCharset == null ? (0, decoder_1.detectCharset)(buffer) : options.forcedCharset;
const callback = options.progressCallback;
const totalBytes = buffer.byteLength;
const decodingCallback = callback ? (bytesRead) => callback(0 /* GedcomReadingPhase.Decoding */, bytesRead / totalBytes) : undefined;
let input;
if (charset === "UTF-8" /* FileEncoding.Utf8 */ || charset === "UTF-16be" /* FileEncoding.Utf16be */ || charset === "UTF-16le" /* FileEncoding.Utf16le */) {
input = (0, decoding_1.decodeUtf)(buffer, decodingCallback);
}
else if (charset === "Cp1252" /* FileEncoding.Cp1252 */) {
input = (0, decoding_1.decodeCp1252)(buffer, decodingCallback);
}
else if (charset === "ANSEL" /* FileEncoding.Ansel */) {
input = (0, decoding_1.decodeAnsel)(buffer, decodingCallback, !!options.doStrictDecoding);
}
else if (charset === "Macintosh" /* FileEncoding.Macintosh */) {
input = (0, decoding_1.decodeMacintosh)(buffer, decodingCallback);
}
else if (charset === "Cp850" /* FileEncoding.Cp850 */) {
input = (0, decoding_1.decodeCp850)(buffer, decodingCallback);
}
else {
throw new error_1.ErrorUnsupportedCharset(`Unsupported charset: ${charset}`, charset);
}
const totalChars = input.length;
const tokensIterator = (0, tokenizer_1.tokenize)(input);
const rootNode = (0, structurer_1.buildTree)(tokensIterator, !!options.noInlineContinuations, callback ? charsRead => callback(1 /* GedcomReadingPhase.TokenizationAndStructuring */, charsRead / totalChars) : null);
checkTreeStructure(rootNode);
if (!options.noIndex) {
(0, indexer_1.indexTree)(rootNode, !!options.noBackwardsReferencesIndex, !!options.doHideIndex, callback ? () => callback(2 /* GedcomReadingPhase.Indexing */, null) : null);
}
if (options.doFreeze) {
if (callback) {
callback(3 /* GedcomReadingPhase.Freezing */, 0);
}
deepFreeze(rootNode);
if (callback) {
callback(3 /* GedcomReadingPhase.Freezing */, 1);
}
}
return rootNode;
};
exports.parseGedcom = parseGedcom;
/**
* A simple and fast testing procedure to eliminate files that are clearly not Gedcoms.
* @param buffer The content of the file
*/
const checkMagicHeader = (buffer) => {
const headStr = '0 HEAD';
const head = [];
for (let i = 0; i < headStr.length; i++) {
head.push(headStr.charCodeAt(i));
}
const byteBuffer = new Uint8Array(buffer);
const startsWith = (bytes) => {
if (byteBuffer.byteLength < bytes.length) {
return false;
}
for (let i = 0; i < bytes.length; i++) {
if (bytes[i] !== byteBuffer[i]) {
return false;
}
}
return true;
};
if (!startsWith(head) && !startsWith(decoding_1.BOM_UTF8.concat(head))) { // Not ASCII nor any of its extensions, including UTF-8
const headUtf16 = head.map(b => [0, b]);
if (!startsWith(decoding_1.BOM_UTF16_BE.concat(headUtf16.flat())) &&
!startsWith(decoding_1.BOM_UTF16_LE.concat(headUtf16.map(bs => bs.slice().reverse()).flat()))) { // Not UTF-16
const headUtf32 = head.map(b => [0, 0, 0, b]);
if (!startsWith(decoding_1.BOM_UTF32_BE.concat(headUtf32.flat())) &&
!startsWith(decoding_1.BOM_UTF32_LE.concat(headUtf32.map(bs => bs.slice().reverse()).flat()))) { // Not UTF-32
throw new error_1.ErrorInvalidFileType('Probably not a Gedcom file');
}
}
}
};
/**
* A simple procedure verifying that the root node starts with a {@link Tag.Header} and ends with a {@link Tag.Trailer}.
* @param rootNode The root node
*/
const checkTreeStructure = (rootNode) => {
const root = rootNode.children;
// Assumes that `root.length > 0`
const header = root[0];
if (header.tag !== "HEAD" /* Tag.Header */) {
throw new error_1.ErrorTreeStructure(`First node is not a header (got ${header.tag})`);
}
const trailer = root[root.length - 1];
if (trailer.tag !== "TRLR" /* Tag.Trailer */) {
throw new error_1.ErrorTreeStructure(`Last node is not a trailer (got ${trailer.tag})`);
}
};
/**
* Freezes this object to prevent further modifications.
* @param object The object to be frozen
*/
const deepFreeze = (object) => {
let queue = [object];
while (queue.length > 0) {
const next = [];
queue.forEach(obj => {
if (obj != null && typeof obj === 'object' && !Object.isFrozen(obj)) {
Object.freeze(obj);
Object.getOwnPropertyNames(obj).forEach(property => next.push(obj[property]));
}
});
queue = next;
}
};
//# sourceMappingURL=reader.js.map
@@ -0,0 +1 @@
{"version":3,"file":"reader.js","sourceRoot":"","sources":["../../../src/parse/reader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
import { TreeNodeRoot } from '../tree';
/**
* Builds a tree from tokenized Gedcom lines.
* @param lines An iterable of regular expression matches, which format is defined in {@link tokenize}
* @param noInlineContinuations See {@link GedcomReadingOptions.noInlineContinuations}
* @param progressCallback See {@link GedcomReadingPhase.progressCallback}
*/
export declare const buildTree: (lines: Iterable<RegExpExecArray>, noInlineContinuations?: boolean, progressCallback?: ((charsRead: number) => void) | null) => TreeNodeRoot;
@@ -0,0 +1,83 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildTree = void 0;
const error_1 = require("./error");
const PROGRESS_INTERVAL = 50000;
/**
* Builds a tree from tokenized Gedcom lines.
* @param lines An iterable of regular expression matches, which format is defined in {@link tokenize}
* @param noInlineContinuations See {@link GedcomReadingOptions.noInlineContinuations}
* @param progressCallback See {@link GedcomReadingPhase.progressCallback}
*/
const buildTree = (lines, noInlineContinuations = false, progressCallback = null) => {
if (progressCallback) {
progressCallback(0);
}
let i = 0;
let charsRead = 0;
let currentLevel = -1; // Current level
const stack = [{ tag: null, pointer: null, value: null, indexSource: -1, indexRelative: 0, children: [] }];
for (const line of lines) {
const [lineStr, levelStr, pointer, tag, value] = line;
// There is an unsolvable ambiguity here, so we just try our best and assume it is correct
const valueUnescaped = value ? value.replace(/@@/g, '@') : value;
charsRead += lineStr.length;
const level = parseInt(levelStr);
const isSameOrUpperLevel = level <= currentLevel, isDownLevel = level === currentLevel + 1;
if (level < 0 || (!isSameOrUpperLevel && !isDownLevel)) {
throw new error_1.ErrorInvalidNesting(`Illegal nesting level at line ${i + 1} (current is ${currentLevel}, got ${level})`, i + 1, currentLevel, level);
}
const levelDifference = currentLevel - level + 1;
for (let j = 0; j < levelDifference; j++) { // Go up
stack.pop();
}
const parent = stack[stack.length - 1];
const siblings = parent.children;
if (tag === "CONC" /* Tag.Concatenation */ && !noInlineContinuations) { // TODO: (potentially) inefficient string concatenation
if (pointer) {
throw new error_1.ErrorInvalidConcatenation(`Illegal concatenation format at line ${i + 1}`, i + 1, "CONC" /* Tag.Concatenation */);
}
if (!parent) {
throw new error_1.ErrorInvalidConcatenation(`Concatenation with no parent at line ${i + 1}`, i + 1, "CONC" /* Tag.Concatenation */);
}
if (parent.value == null) {
parent.value = '';
}
parent.value += valueUnescaped !== null && valueUnescaped !== void 0 ? valueUnescaped : '';
currentLevel = level - 1;
}
else if (tag === "CONT" /* Tag.Continuation */ && !noInlineContinuations) {
if (pointer) {
throw new error_1.ErrorInvalidConcatenation(`Illegal continuation format at line ${i + 1}`, i + 1, "CONT" /* Tag.Continuation */);
}
if (!parent) {
throw new error_1.ErrorInvalidConcatenation(`Continuation with no parent at line ${i + 1}`, i + 1, "CONT" /* Tag.Continuation */);
}
const separator = '\n'; // TODO: hardcoded separator
if (parent.value == null) {
parent.value = '';
}
parent.value += separator + (valueUnescaped !== null && valueUnescaped !== void 0 ? valueUnescaped : '');
currentLevel = level - 1;
}
else {
const child = { tag, pointer: pointer !== null && pointer !== void 0 ? pointer : null, value: valueUnescaped !== null && valueUnescaped !== void 0 ? valueUnescaped : null, indexSource: i, indexRelative: parent.children.length, children: [] };
siblings.push(child);
if (pointer && level > 0) {
throw new error_1.ErrorInvalidRecordDefinition(`Record must be a top-level definition at line ${i + 1}`, i + 1);
}
stack.push(child);
currentLevel = level;
}
i++;
if (progressCallback && i % PROGRESS_INTERVAL === 0) {
progressCallback(charsRead);
}
}
if (progressCallback) {
progressCallback(charsRead);
}
return stack[0]; // The top of the stack is the root node
};
exports.buildTree = buildTree;
//# sourceMappingURL=structurer.js.map
@@ -0,0 +1 @@
{"version":3,"file":"structurer.js","sourceRoot":"","sources":["../../../src/parse/structurer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
/**
* Processes the input string and return a tokenized, line by line, high-level representation.
* @param input The input file, represented as a single string
* @param strict When set to <code>false</code> any parsing exception will not be reported
*/
export declare const tokenize: (input: string, strict?: boolean) => Iterable<RegExpExecArray>;
@@ -0,0 +1,70 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.tokenize = void 0;
const error_1 = require("./error");
const ccAlpha = 'A-Za-z';
const ccDigit = '0-9', ccNonZeroDigit = '1-9';
const ccAlphanum = `${ccAlpha}${ccDigit}`;
const cSpace = ' ';
const cDelim = `${cSpace}`;
const gEscapeText = `[${ccAlphanum}][${ccAlphanum}${cSpace}]*`;
const gEscape = `@#(?:${gEscapeText})@`;
const gIdentifierString = `[${ccAlphanum}-_]+`; // x: Allow '-' and '_'
const gLevel = `[${ccNonZeroDigit}][${ccDigit}]+|[${ccDigit}]`;
const ccDisallowed = '\\x00-\\x08\\x0A-\\x1F'; // x: include \xFF
const cCR = '\\r', cLF = '\\n';
const gLineChar = `[^${ccDisallowed}${cCR}${cLF}@]|@`; // x: Allow single at
const gLineText = `(?:${gLineChar})*`; // x: Allow empty strings
const gLineItem = `${gEscape}|${gLineText}|${gEscape}[${cDelim}]${gLineText}`;
const gXRefId = `@${gIdentifierString}@`;
const gPointer = `${gXRefId}`;
const gLineValue = `${gPointer}|(?:${gLineItem})`;
const gTag = `[${ccAlphanum}]+|_[${ccAlphanum}_]+`; // TODO
const gTerminator = `${cCR}${cLF}?|${cLF}`; // x: Allow \r
const gGedcomLine = `(${gLevel})(?:${cDelim}(${gXRefId}))?${cDelim}(${gTag})(?:${cDelim}(${gLineValue}))?(${gTerminator}|$)`; // x: Allow no trailing newline
/**
* The tokenizer implementation.
* Processes a file stored as a string, line by line, according to the `gGedcomLine` regular expression.
* A parameter in the constructor decides whether to raise an error when a line cannot be parsed or to fail silently.
* Code was not extracted further as a performance tradeoff.
*/
class GedcomTokenizer {
constructor(input, strict) {
this.input = input;
this.strict = strict;
this.rGedcomLines = new RegExp(`^${gGedcomLine}`, 'gym'); // Must be newly created
this.linesRead = 0;
this.charactersRead = 0;
} // eslint-disable-line no-useless-constructor
[Symbol.iterator]() {
return this;
}
next() {
const result = this.rGedcomLines.exec(this.input);
if (result === null || (result[5].length === 0 && this.charactersRead + result[0].length !== this.input.length)) {
if (result !== null) {
this.charactersRead += result[0].length;
}
const success = this.charactersRead === this.input.length;
if (this.strict && !success) {
const printCharactersMax = 256; // Avoid printing a super long line
const errorLine = this.input.substring(this.charactersRead, Math.min(this.charactersRead + printCharactersMax, this.input.length)).split(/[\r\n]+/, 1)[0];
throw new error_1.ErrorTokenization(`Invalid format for line ${this.linesRead + 1}: "${errorLine}"`, this.linesRead + 1, errorLine);
}
return { done: true, value: null }; // Return
}
else {
this.charactersRead += result[0].length; // Includes terminator
this.linesRead++;
return { done: false, value: result }; // Yield
}
}
}
/**
* Processes the input string and return a tokenized, line by line, high-level representation.
* @param input The input file, represented as a single string
* @param strict When set to <code>false</code> any parsing exception will not be reported
*/
const tokenize = (input, strict = true) => new GedcomTokenizer(input, strict);
exports.tokenize = tokenize;
//# sourceMappingURL=tokenizer.js.map
@@ -0,0 +1 @@
{"version":3,"file":"tokenizer.js","sourceRoot":"","sources":["../../../src/parse/tokenizer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
export interface ValueAge {
isGreaterThan: boolean;
isLessThan: boolean;
hasDate: boolean;
date?: {
years: number;
months: number;
days: number;
};
isChild: boolean;
isInfant: boolean;
isStillborn: boolean;
}
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=ValueAge.js.map
@@ -0,0 +1 @@
{"version":3,"file":"ValueAge.js","sourceRoot":"","sources":["../../../../src/parse/value/ValueAge.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
export interface ValueExactDate {
day: number;
month: number;
year: number;
}
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=ValueExactDate.js.map
@@ -0,0 +1 @@
{"version":3,"file":"ValueExactDate.js","sourceRoot":"","sources":["../../../../src/parse/value/ValueExactDate.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
export interface ValueExactTime {
hours: number;
minutes: number;
seconds?: number;
centiseconds?: number;
}
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=ValueExactTime.js.map
@@ -0,0 +1 @@
{"version":3,"file":"ValueExactTime.js","sourceRoot":"","sources":["../../../../src/parse/value/ValueExactTime.ts"],"names":[],"mappings":""}
@@ -0,0 +1 @@
export declare type ValueNameParts = (string | undefined)[] & [string | undefined, string | undefined, string | undefined] & ([string, string, string] | [undefined, string, string] | [string, string, undefined] | [undefined, string, undefined] | [string, undefined, undefined]);
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=ValueNameParts.js.map
@@ -0,0 +1 @@
{"version":3,"file":"ValueNameParts.js","sourceRoot":"","sources":["../../../../src/parse/value/ValueNameParts.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
import { ValueAge } from './ValueAge';
/**
* Parses an age value.
* @param value The value to parse
* @category Value parsers
*/
export declare const parseAge: (value: string | null) => ValueAge | null;
@@ -0,0 +1,73 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseAge = void 0;
/**
* Parses an age value.
* @param value The value to parse
* @category Value parsers
*/
const parseAge = (value) => {
if (!value) {
return null;
}
const sign = '<>'.indexOf(value[0]);
const hasSign = sign >= 0;
const remaining = hasSign ? value.substring(1) : value;
const isChild = remaining === 'CHILD';
const isInfant = remaining === 'INFANT';
const isStillborn = remaining === 'STILLBORN';
const common = { isGreaterThan: sign === 1, isLessThan: sign === 0, isChild, isInfant, isStillborn };
if (isChild || isInfant || isStillborn) {
return Object.assign({ hasDate: false }, common);
}
else {
const parts = remaining.split(' ');
if (parts.length > 3) {
return null;
}
const rNumber = /^(?:0|[1-9][0-9]{0,2})$/;
const rFormat = /^(?:ymd|y|m|d|ym|yd|md)$/;
const result = parts.map(part => {
if (part.length < 2) {
return null;
}
const suffix = part[part.length - 1];
if (!'ymd'.includes(suffix)) {
return null;
}
const init = part.substring(0, part.length - 1);
if (init.match(rNumber) !== null) {
const number = parseInt(init);
if ((suffix === 'd' && number > 365) || (suffix === 'm' && number > 11)) {
return null;
}
return [suffix, number];
}
else {
return null;
}
});
if (result.includes(null)) {
return null;
}
const resultNonNull = result;
if (resultNonNull.map(r => r[0]).join('').match(rFormat) === null) {
return null;
}
let years = 0, months = 0, days = 0;
resultNonNull.forEach(([identifier, number]) => {
if (identifier === 'y') {
years = number;
}
else if (identifier === 'm') {
months = number;
}
else {
days = number;
}
});
return Object.assign({ hasDate: true, date: { years, months, days } }, common);
}
};
exports.parseAge = parseAge;
//# sourceMappingURL=age.js.map
@@ -0,0 +1 @@
{"version":3,"file":"age.js","sourceRoot":"","sources":["../../../../src/parse/value/age.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
/**
* @param value
* @category Value parsers
*/
export declare const parseLatitude: (value: string | null) => number | null;
/**
* @param value
* @category Value parsers
*/
export declare const parseLongitude: (value: string | null) => number | null;
@@ -0,0 +1,34 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseLongitude = exports.parseLatitude = void 0;
const parseCoordinate = (regex, orientation, value) => {
if (!value) {
return null;
}
const groups = regex.exec(value);
if (!groups) {
return null;
}
const sign = groups[1] !== undefined ? orientation[groups[1]] : groups[2] === '-' ? -1 : 1;
const decimal = parseFloat(groups[3]);
return sign * decimal;
};
/**
* @param value
* @category Value parsers
*/
const parseLatitude = (value) => {
const rLatitude = /^(?:([NS])|([+-]?))([0-9]{1,2}(?:\.[0-9]{1,6})?)$/;
return parseCoordinate(rLatitude, { N: 1, S: -1 }, value);
};
exports.parseLatitude = parseLatitude;
/**
* @param value
* @category Value parsers
*/
const parseLongitude = (value) => {
const rLongitude = /^(?:([EW])|([+-]?))([0-9]{1,3}(?:\.[0-9]{1,6})?)$/;
return parseCoordinate(rLongitude, { E: 1, W: -1 }, value);
};
exports.parseLongitude = parseLongitude;
//# sourceMappingURL=coordinates.js.map
@@ -0,0 +1 @@
{"version":3,"file":"coordinates.js","sourceRoot":"","sources":["../../../../src/parse/value/coordinates.ts"],"names":[],"mappings":";;;AAAA,MAAM,eAAe,GAAG,CAAC,KAAa,EAAE,WAAuC,EAAE,KAAoB,EAAiB,EAAE;IACpH,IAAI,CAAC,KAAK,EAAE;QACR,OAAO,IAAI,CAAC;KACf;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACjC,IAAI,CAAC,MAAM,EAAE;QACT,OAAO,IAAI,CAAC;KACf;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3F,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,OAAO,IAAI,GAAG,OAAO,CAAC;AAC1B,CAAC,CAAC;AAEF;;;GAGG;AACI,MAAM,aAAa,GAAG,CAAC,KAAoB,EAAiB,EAAE;IACjE,MAAM,SAAS,GAAG,mDAAmD,CAAC;IACtE,OAAO,eAAe,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;AAC9D,CAAC,CAAC;AAHW,QAAA,aAAa,iBAGxB;AAEF;;;GAGG;AACI,MAAM,cAAc,GAAG,CAAC,KAAoB,EAAiB,EAAE;IAClE,MAAM,UAAU,GAAG,mDAAmD,CAAC;IACvE,OAAO,eAAe,CAAC,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;AAC/D,CAAC,CAAC;AAHW,QAAA,cAAc,kBAGzB"}
@@ -0,0 +1,16 @@
import { ValueDate } from './dates';
import { ValueExactDate } from './ValueExactDate';
/**
* Parses a Gedcom date. These dates can take many different forms, see {@link ValueDate}.
* The dates are checked for validity with respect to their calendar, except for the Hebrew calendar which will assume all dates to be valid due to a missing implementation.
* Any unsuccessful parsing or invalid date(s) will result in <code>null</code>.
* @param value The value to parse
* @category Value parsers
*/
export declare const parseDate: (value: string | null) => ValueDate | null;
/**
* Parses a date of format day-month-year.
* @param value The value to parse
* @category Value parsers
*/
export declare const parseExactDate: (value: string | null) => ValueExactDate | null;
@@ -0,0 +1,380 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseExactDate = exports.parseDate = void 0;
const CALENDAR_GREGORIAN = 'DGREGORIAN', CALENDAR_JULIAN = 'DJULIAN', CALENDAR_HEBREW = 'DHEBREW', CALENDAR_FRENCH_REPUBLICAN = 'DFRENCH R', CALENDAR_UNKNOWN = 'DUNKNOWN';
const DATE_PERIOD_FROM = 'FROM', DATE_PERIOD_TO = 'TO';
const DATE_RANGE_BEFORE = 'BEF', DATE_RANGE_AFTER = 'AFT', DATE_RANGE_BETWEEN = 'BET', DATE_RANGE_AND = 'AND';
const DATE_APPROXIMATED_ABOUT = 'ABT', DATE_APPROXIMATED_CALCULATED = 'CAL', DATE_APPROXIMATED_ESTIMATED = 'EST';
const DATE_INT = 'INT';
const createIndices = (array, looseCase = false) => {
// Start with 1 to preserve the month numbers
const entries = array.map((value, i) => [value, i + 1]);
const capitalizeFirst = (v) => v ? v[0].toUpperCase() + v.substring(1).toLowerCase() : v;
const finalEntries = looseCase ? entries.concat(entries.map(([value, n]) => [capitalizeFirst(value), n])) : entries;
return Object.fromEntries(finalEntries);
};
const MONTHS_VALUES = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC'];
const MONTHS_FRENCH_VALUES = ['VEND', 'BRUM', 'FRIM', 'NIVO', 'PLUV', 'VENT', 'GERM', 'FLOR', 'PRAI', 'MESS', 'THER', 'FRUC', 'COMP'];
const MONTHS_HEBREW_VALUES = ['TSH', 'CSH', 'KSL', 'TVT', 'SHV', 'ADR', 'ADS', 'NSN', 'IYR', 'SVN', 'TMZ', 'AAV', 'ELL'];
const MONTHS = createIndices(MONTHS_VALUES, true); // Old software format months that way, so we allow them
const MONTHS_FRENCH = createIndices(MONTHS_FRENCH_VALUES);
const MONTHS_HEBREW = createIndices(MONTHS_HEBREW_VALUES);
const BEFORE_COMMON_ERA = createIndices(['BCE', 'BC', 'B.C.']);
const rDateCalendarEscape = /^@#(.*)@$/; // FIXME
const rDatePhrase = /^\((.*)\)$/;
const rDatePhraseEnd = /\((.*)\)$/;
const gYear = '([1-9][0-9]*|0|00[1-9]|0[1-9][0-9])';
const rYear = new RegExp(`^${gYear}$`);
const rYearDual = new RegExp(`^${gYear}/([0-9]{2})$`);
const rDay = /^(?:0?[1-9]|[1-2][0-9]|3[0-1])$/; // Allow leading zeros
const daysInJulianMonth = (month, isBissextile) => month === 2 ? 28 + (isBissextile ? 1 : 0) : 30 + ([4, 6, 9, 11].includes(month) ? 0 : 1);
const isValidPartialDateJulian = (isBissextile, month, day) => {
if (month != null) {
if (month < 1 || month > MONTHS_VALUES.length) { // This check is redundant, but included for completeness
return false;
}
if (day != null) {
const daysInMonth = daysInJulianMonth(month, isBissextile);
if (day < 1 || day > daysInMonth) {
return false;
}
}
}
return true;
};
const isValidDateGregorian = (year, month, day) => {
const isBissextile = ((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0);
return isValidPartialDateJulian(isBissextile, month, day);
};
const isValidDateJulian = (year, month, day) => {
const isBissextile = year % 4 === 0;
return isValidPartialDateJulian(isBissextile, month, day);
};
const isValidDateFrenchRepublican = (year, month, day) => {
if (!(year >= 1 && year <= 14)) {
return false;
}
if (month != null) {
if (month < 1 || month > MONTHS_FRENCH_VALUES.length) {
return false;
}
if (day != null) {
const isBissextile = year % 4 === 3;
const daysInMonth = month !== 13 ? 30 : 5 + (isBissextile ? 1 : 0);
if (day < 1 || day > daysInMonth) {
return false;
}
}
}
return true;
};
const isValidHebrew = (year, month, day) => {
if (year < 1) { // Hebrew calendar is not proleptic
return false;
}
if (month != null) {
if (month < 1 || month > MONTHS_HEBREW_VALUES.length) {
return false;
}
if (day != null) {
const numberOfDays = 29 + ([1, 5, 6, 8, 10, 12].includes(month) ? 1 : 0) + (month === 2 || month === 3 ? 1 : 0); // TODO: this check is not strict enough
if (day < 1 || day > numberOfDays) {
return false;
}
}
}
return true;
};
/**
* Parses a Gedcom date. These dates can take many different forms, see {@link ValueDate}.
* The dates are checked for validity with respect to their calendar, except for the Hebrew calendar which will assume all dates to be valid due to a missing implementation.
* Any unsuccessful parsing or invalid date(s) will result in <code>null</code>.
* @param value The value to parse
* @category Value parsers
*/
const parseDate = (value) => {
if (!value) {
return null;
}
value = value.trim(); // Some files contain leading/trailing spaces
const defaultDateKinds = {
hasDate: true,
hasPhrase: false,
isDatePunctual: false,
isDatePeriod: false,
isDateRange: false,
isDateApproximated: false,
isDateInterpreted: false,
};
let textMatch;
if ((textMatch = rDatePhrase.exec(value)) !== null) {
const text = textMatch[1];
return Object.assign(Object.assign({}, defaultDateKinds), { hasDate: false, hasPhrase: true, phrase: text });
}
const parts = [];
let j = 0;
const spaceChar = ' ', escapeStart = '@#', escapeEndChar = '@';
for (let k = 0; k < value.length; k++) {
if (value.substring(k, k + escapeStart.length) === escapeStart) {
k += escapeStart.length;
while (k < value.length && value[k] !== escapeEndChar) {
k++;
}
}
else {
if (value[k] === spaceChar) {
parts.push(value.substring(j, k));
j = k + 1;
}
}
}
parts.push(value.substring(j, value.length));
let i = 0;
const parseYearPart = (parts, allowBce, allowDual) => {
const defaultYearModifiers = {
isBce: false,
isDual: false,
};
let dual;
if (i < parts.length && rYear.exec(parts[i]) !== null) {
const value = parseInt(parts[i]);
i++;
if (allowBce) {
let isBce = false;
if (i < parts.length && BEFORE_COMMON_ERA[parts[i]] !== undefined) {
isBce = true;
i++;
}
return Object.assign(Object.assign({}, defaultYearModifiers), { value,
isBce });
}
else {
return Object.assign(Object.assign({}, defaultYearModifiers), { value });
}
}
else if (allowDual && i < parts.length && (dual = rYearDual.exec(parts[i])) !== null) {
const value = parseInt(dual[1]), valueDual = parseInt(dual[2]);
i++;
return Object.assign(Object.assign({}, defaultYearModifiers), { value, isDual: true, valueDual });
}
else {
return null; // Underflow or not a year
}
};
const parseDatePart = (parts) => {
var _a;
if (i < parts.length) {
let escapeMatch;
let calendar = CALENDAR_GREGORIAN;
if ((escapeMatch = rDateCalendarEscape.exec(parts[i])) !== null) { // Starts with a calendar
calendar = (_a = escapeMatch[1]) !== null && _a !== void 0 ? _a : escapeMatch[2];
i++;
}
const isGregorian = calendar === CALENDAR_GREGORIAN, isJulian = calendar === CALENDAR_JULIAN, isHebrew = calendar === CALENDAR_HEBREW, isFrenchRepublican = calendar === CALENDAR_FRENCH_REPUBLICAN, isUnknown = calendar === CALENDAR_UNKNOWN;
const isGregorianOrJulian = isGregorian || isJulian;
const calendarProps = {
isGregorian, isJulian, isHebrew, isFrenchRepublican, isUnknown,
};
let monthsIndices;
if (isGregorian || isJulian) {
monthsIndices = MONTHS;
}
else if (isHebrew) {
monthsIndices = MONTHS_HEBREW;
}
else if (isFrenchRepublican) {
monthsIndices = MONTHS_FRENCH;
}
else {
return null; // Unknown/invalid calendar
}
let monthIndex;
if (i < parts.length && (monthIndex = monthsIndices[parts[i]]) !== undefined) { // Format month-year
i++;
const year = parseYearPart(parts, false, isGregorianOrJulian);
if (year !== null) {
if ((isGregorian && !isValidDateGregorian(year.value, monthIndex)) ||
(isJulian && !isValidDateJulian(year.value, monthIndex)) ||
(isFrenchRepublican && !isValidDateFrenchRepublican(year.value, monthIndex)) ||
(isHebrew && !isValidHebrew(year.value, monthIndex))) {
return null;
}
return {
calendar: calendarProps,
month: monthIndex,
year: year,
};
}
else {
return null; // Invalid year
}
}
else {
const previousI = i;
const firstAsYear = parseYearPart(parts, isGregorianOrJulian, false);
if (firstAsYear !== null && firstAsYear.isBce) {
return {
calendar: calendarProps,
year: firstAsYear,
};
}
i = previousI; // Important: we need to backtrack since there can be an ambiguity
const firstAsDay = i < parts.length && rDay.exec(parts[i]) !== null ? parseInt(parts[i]) : null;
let secondAsMonth = null;
if (firstAsDay !== null && i + 1 < parts.length) {
const month = monthsIndices[parts[i + 1]];
if (month !== undefined) {
secondAsMonth = month;
}
}
// Remark that `secondAsMonth !== null` implies `firstAsDay !== null`; but the type checker cannot infer it
if (firstAsDay !== null && secondAsMonth !== null) { // Format day-month-year
i += 2;
const year = parseYearPart(parts, false, isGregorianOrJulian);
if (year !== null) {
if ((isGregorian && !isValidDateGregorian(year.value, secondAsMonth, firstAsDay)) ||
(isJulian && !isValidDateJulian(year.value, secondAsMonth, firstAsDay)) ||
(isFrenchRepublican && !isValidDateFrenchRepublican(year.value, secondAsMonth, firstAsDay)) ||
(isHebrew && !isValidHebrew(year.value, secondAsMonth, firstAsDay))) {
return null;
}
return {
calendar: calendarProps,
day: firstAsDay,
month: secondAsMonth,
year: year,
};
}
else {
return null; // Invalid year (or the format is day-month, which is not supported here)
}
}
else if (firstAsYear !== null) { // Format year
i++;
if ((isFrenchRepublican && !isValidDateFrenchRepublican(firstAsYear.value)) ||
(isHebrew && !isValidHebrew(firstAsYear.value))) {
return null;
}
return {
calendar: calendarProps,
year: firstAsYear,
};
}
else {
return null; // Invalid year (or first token)
}
}
}
else {
return null; // Underflow
}
};
i++;
if (parts.length === 0) {
return null; // Underflow
}
else if (parts[0] === DATE_PERIOD_FROM) {
const date = parseDatePart(parts);
if (date !== null) {
if (i === parts.length) { // Only from
return Object.assign(Object.assign({}, defaultDateKinds), { isDatePeriod: true, dateFrom: date });
}
if (i < parts.length && parts[i] === DATE_PERIOD_TO) {
i++;
const date2 = parseDatePart(parts);
if (date2 !== null && i === parts.length) { // Only from
return Object.assign(Object.assign({}, defaultDateKinds), { isDatePeriod: true, dateFrom: date, dateTo: date2 });
}
}
}
}
else if (parts[0] === DATE_PERIOD_TO) {
const date = parseDatePart(parts);
if (date !== null && i === parts.length) {
return Object.assign(Object.assign({}, defaultDateKinds), { isDatePeriod: true, dateTo: date });
}
}
else if (parts[0] === DATE_RANGE_BEFORE) {
const date = parseDatePart(parts);
if (date !== null && i === parts.length) {
return Object.assign(Object.assign({}, defaultDateKinds), { isDateRange: true, dateBefore: date });
}
}
else if (parts[0] === DATE_RANGE_AFTER) {
const date = parseDatePart(parts);
if (date !== null && i === parts.length) {
return Object.assign(Object.assign({}, defaultDateKinds), { isDateRange: true, dateAfter: date });
}
}
else if (parts[0] === DATE_RANGE_BETWEEN) {
const date1 = parseDatePart(parts);
if (date1 !== null) {
if (parts[i] === DATE_RANGE_AND) {
i++;
const date2 = parseDatePart(parts);
if (date2 !== null && i === parts.length) {
return Object.assign(Object.assign({}, defaultDateKinds), { isDateRange: true, dateAfter: date1, dateBefore: date2 });
}
}
}
}
else if (parts[0] === DATE_APPROXIMATED_ABOUT || parts[0] === DATE_APPROXIMATED_CALCULATED || parts[0] === DATE_APPROXIMATED_ESTIMATED) {
const date = parseDatePart(parts);
if (date !== null && i === parts.length) {
return Object.assign(Object.assign({}, defaultDateKinds), { isDatePunctual: true, isDateApproximated: true, approximationKind: {
isAbout: parts[0] === DATE_APPROXIMATED_ABOUT,
isCalculated: parts[0] === DATE_APPROXIMATED_CALCULATED,
isEstimated: parts[0] === DATE_APPROXIMATED_ESTIMATED,
}, date });
}
}
else if (parts[0] === DATE_INT) {
const date = parseDatePart(parts);
if (date !== null) {
const phraseEnd = rDatePhraseEnd.exec(value);
if (phraseEnd !== null) {
const text = phraseEnd[1];
return Object.assign(Object.assign({}, defaultDateKinds), { hasPhrase: true, isDatePunctual: true, isDateInterpreted: true, date, phrase: text });
}
}
}
else { // Normal date
i--;
const date = parseDatePart(parts);
if (date !== null && i === parts.length) {
return Object.assign(Object.assign({}, defaultDateKinds), { isDatePunctual: true, date });
}
}
return null; // All other invalid cases
};
exports.parseDate = parseDate;
/**
* Parses a date of format day-month-year.
* @param value The value to parse
* @category Value parsers
*/
const parseExactDate = (value) => {
if (!value) {
return null;
}
value = value.trim();
const parts = value.split(' ');
if (parts.length !== 3) { // Must contain three parts: day, month, year
return null;
}
const month = MONTHS[parts[1]];
if (rDay.exec(parts[0]) !== null && month !== undefined && rYear.exec(parts[2]) !== null) {
const day = parseInt(parts[0]);
const year = parseInt(parts[2]);
return {
day,
month,
year,
};
}
else { // Invalid date
return null;
}
};
exports.parseExactDate = parseExactDate;
//# sourceMappingURL=date.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,22 @@
import { ValuePartDate } from './dates';
import { ValueExactDate } from './ValueExactDate';
import { ValueExactTime } from './ValueExactTime';
/**
* Converts a parsed Gedcom date to its corresponding JS date (expressed in the Gregorian calendar).
* The supported calendars are: Gregorian, Julian and French Republican.
* The Hebrew calendar is not yet supported. Unknown calendars are inherently unsupported.
* Dual dates will not be converted. BCE dates will be converted assuming the existence of year 0.
* In any of these cases the returned value will be <code>null</code>.
* The argument is assumed to be correct, that is of correct format and valid date.
* This is already guaranteed by {@link parseDate}.
* @param date The parsed date to convert
* @category Parsed value converters
*/
export declare const toJsDate: (date: ValuePartDate) => Date | null;
/**
* Converts a parsed Gedcom date and optional time into the corresponding JS datetime.
* @param date The parsed date
* @param time And optional parsed time
* @category Parsed value converters
*/
export declare const toJsDateTime: (date: ValueExactDate, time?: ValueExactTime) => Date | null;
@@ -0,0 +1,105 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.toJsDateTime = exports.toJsDate = void 0;
/**
* Convert a Julian day number (JDN) into its corresponding JS date.
* @param jdn The Julian day number
*/
const julianDayNumberToJsDate = (jdn) => {
// Conversion of a Julian day number to a Gregorian date
const j = jdn + 32044;
const cst1 = 146097;
const g = Math.floor(j / cst1);
const dg = j % cst1;
const cst2 = 36524;
const c = Math.floor((Math.floor(dg / cst2) + 1) * 3 / 4);
const dc = dg - c * cst2;
const cst3 = 1461;
const b = Math.floor(dc / cst3);
const db = dc % cst3;
const cst4 = 365;
const a = Math.floor((Math.floor(db / cst4) + 1) * 3 / 4);
const da = db - a * cst4;
const y = g * 400 + c * 100 + b * 4 + a;
const cst5 = 153;
const m = Math.floor((da * 5 + 308) / cst5) - 2;
const d = da - Math.floor((m + 4) * cst5 / 5) + 122;
const cst6 = 12;
const gYear = y - 4800 + Math.floor((m + 2) / cst6);
const gMonth = (m + 2) % cst6; // Starts at 0!
const gDay = d + 1;
return new Date(Date.UTC(gYear, gMonth, gDay));
};
/**
* Converts a parsed Gedcom date to its corresponding JS date (expressed in the Gregorian calendar).
* The supported calendars are: Gregorian, Julian and French Republican.
* The Hebrew calendar is not yet supported. Unknown calendars are inherently unsupported.
* Dual dates will not be converted. BCE dates will be converted assuming the existence of year 0.
* In any of these cases the returned value will be <code>null</code>.
* The argument is assumed to be correct, that is of correct format and valid date.
* This is already guaranteed by {@link parseDate}.
* @param date The parsed date to convert
* @category Parsed value converters
*/
const toJsDate = (date) => {
var _a, _b;
const day = (_a = date.day) !== null && _a !== void 0 ? _a : 1; // Dirty; if you find a better way to do it, submit PR
const month = (_b = date.month) !== null && _b !== void 0 ? _b : 1;
const year = date.year.isBce ? -date.year.value : date.year.value; // We consider the existence of year 0
if (date.year.isDual) {
return null; // Dual years are unsupported (and rarely ever used anyway)
}
if (date.calendar.isGregorian) {
return new Date(Date.UTC(year, month - 1, day)); // All dates are UTC
}
else if (date.calendar.isFrenchRepublican) {
// We only support dates during which the calendar was in use; i.e. 1<=year<=14
const startYear = 1791;
const isB = year % 4 === 0;
const indices = [21, 21, 20, 20, 19, 18, 20, 19, 19, 18, 18, 17, 16];
const [sYear, sMonth, sDay] = [8, 7, 1];
const index = indices[month - 1] +
(month < 7 && isB ? 1 : 0) +
(year > sYear || (year === sYear && (month > sMonth || (month === sMonth && day >= sDay))) ? 1 : 0);
return new Date(Date.UTC(startYear + year + (month > 4 ? 1 : 0), ((month - 1) + 8) % 12, day + index));
}
else if (date.calendar.isJulian) {
// https://en.wikipedia.org/wiki/Julian_day#Converting_Julian_calendar_date_to_Julian_Day_Number
// Compute the Julian day number (JDN) (this is NOT the modified Julian day number (MJD))
// Only positive values are guaranteed to be valid (i.e. J. years >= -4712)
const isNormal = month > 2;
const y = year - (isNormal ? 0 : 1);
const m = month + (isNormal ? 0 : 12);
const jdn = Math.floor((1461 * y + 6884472) / 4) + Math.floor((153 * m - 457) / 5) + day - 1;
return julianDayNumberToJsDate(jdn);
}
else if (date.calendar.isHebrew) {
return null;
}
else {
return null; // Unsupported calendar kind
}
};
exports.toJsDate = toJsDate;
/**
* Converts a parsed Gedcom date and optional time into the corresponding JS datetime.
* @param date The parsed date
* @param time And optional parsed time
* @category Parsed value converters
*/
const toJsDateTime = (date, time) => {
const dt = new Date(Date.UTC(date.year, date.month - 1, date.day));
if (time != null) {
dt.setUTCHours(time.hours); // Important to remain in UTC
dt.setUTCMinutes(time.minutes);
if (time.seconds !== undefined) {
dt.setUTCSeconds(time.seconds);
if (time.centiseconds !== undefined) {
dt.setUTCMilliseconds(time.centiseconds * 10);
}
}
}
return dt;
};
exports.toJsDateTime = toJsDateTime;
//# sourceMappingURL=datejs.js.map
@@ -0,0 +1 @@
{"version":3,"file":"datejs.js","sourceRoot":"","sources":["../../../../src/parse/value/datejs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,202 @@
export interface ValuePartYearBase {
value: number;
isBce: boolean;
isDual: boolean;
}
export interface ValuePartYearNormal extends ValuePartYearBase {
isDual: false;
}
export interface ValuePartYearDual extends ValuePartYearBase {
isDual: true;
valueDual: number;
}
/**
* Stores information about the year.
* Note that the field {@link value} is always a positive integer; if the date is
* BCE then it is indicated by {@link isBce}. The year can also be "dual": although uncommon
* in practice, this means that there is an ambiguity between two years. In that case the second
* year is expressed as a two-digit number and stored in {@link valueDual}.
*/
export declare type ValuePartYear = ValuePartYearNormal | ValuePartYearDual;
export interface ValuePartCalendar {
isGregorian: boolean;
isJulian: boolean;
isHebrew: boolean;
isFrenchRepublican: boolean;
isUnknown: boolean;
}
export interface ValuePartDateYear {
calendar: ValuePartCalendar;
year: ValuePartYear;
}
export interface ValuePartDateMonth extends ValuePartDateYear {
month: number;
}
export interface ValuePartDateDay extends ValuePartDateMonth {
day: number;
}
/**
* Represents a known date or partially known date expressed in a certain calendar.
* It is guaranteed that the fields {@link calendar} and {@link year} are defined.
* Note that the year is not a value but an object, because it contains more information (see {@link ValuePartYear}).
* If defined, both the month and the day start at value 1.
*/
export declare type ValuePartDate = ValuePartDateYear | ValuePartDateMonth | ValuePartDateDay;
/**
* The base type for all date values.
*/
export interface ValueDateBase {
/**
* Indicates an instance of {@link ValueDateDated}.
*/
hasDate: boolean;
/**
* Indicates an instance of {@link ValueDatePhrased}.
*/
hasPhrase: boolean;
/**
* Indicates an instance of {@link ValueDatePunctual}. Implies {@link hasDate}.
*/
isDatePunctual: boolean;
/**
* Indicates an instance of {@link ValueDatePeriod}. Implies {@link hasDate}.
*/
isDatePeriod: boolean;
/**
* Indicates an instance of {@link ValueDateRange}. Implies {@link hasDate}.
*/
isDateRange: boolean;
/**
* Indicates an instance of {@link ValueDateApproximated}. Implies {@link hasDate}.
*/
isDateApproximated: boolean;
/**
* Indicates an instance of {@link ValueDateInterpreted}. Implies {@link hasDate}.
*/
isDateInterpreted: boolean;
}
/**
* An instance is indicated by {@link hasPhrase}.
*/
export interface ValueDatePhrased extends ValueDateBase {
hasPhrase: true;
phrase: string;
isDatePeriod: false;
isDateRange: false;
isDateApproximated: false;
}
/**
* An instance is indicated by the conjunction of {@link hasPhrase} and negated {@link hasDate} (or equivalently, {@link hasPhrase} and negated {@link isDateInterpreted}).
*/
export interface ValueDatePhraseOnly extends ValueDatePhrased {
hasDate: false;
isDatePunctual: false;
isDateApproximated: false;
isDateInterpreted: false;
}
/**
* An instance is indicated by {@link hasDate}.
*/
export interface ValueDateDated extends ValueDateBase {
hasDate: true;
}
/**
* An instance is indicated by {@link isDatePunctual}.
*/
export interface ValueDatePunctual extends ValueDateDated {
isDatePunctual: true;
date: ValuePartDate;
isDatePeriod: false;
isDateRange: false;
}
/**
* An instance is indicated by {@link isDateApproximated}.
*/
export interface ValueDateApproximated extends ValueDatePunctual {
isDateApproximated: true;
approximationKind: {
isAbout: boolean;
isCalculated: boolean;
isEstimated: boolean;
};
hasPhrase: false;
isDateInterpreted: false;
}
/**
* An instance is indicated by {@link isDateInterpreted} (or equivalently by the conjunction of {@link isDatePunctual} and {@link hasPhrase}).
*/
export interface ValueDateInterpreted extends ValueDatePunctual, ValueDatePhrased {
hasDate: true;
isDatePunctual: true;
hasPhrase: true;
isDateInterpreted: true;
isDateApproximated: false;
}
/**
* An instance is indicated by the conjunction of {@link isDatePunctual}, negated {@link isDateApproximated} and negated {@link isDateInterpreted}.
*/
export interface ValueDateNormal extends ValueDatePunctual {
hasPhrase: false;
isDateApproximated: false;
isDateInterpreted: false;
}
/**
* An instance is indicated by {@link isDateRange}.
*/
export interface ValueDateRange extends ValueDateDated {
isDateRange: true;
hasPhrase: false;
isDatePunctual: false;
isDatePeriod: false;
isDateApproximated: false;
isDateInterpreted: false;
}
/**
* An instance is indicated by {@link isDateRange} and defined {@link dateAfter}.
*/
export interface ValueDateRangeAfter extends ValueDateRange {
dateAfter: ValuePartDate;
}
/**
* An instance is indicated by {@link isDateRange} and defined {@link dateBefore}.
*/
export interface ValueDateRangeBefore extends ValueDateRange {
dateBefore: ValuePartDate;
}
/**
* An instance is indicated by {@link isDateRange}, defined {@link dateAfter} and defined {@link dateBefore}.
*/
export interface ValueDateRangeFull extends ValueDateRangeAfter, ValueDateRangeBefore {
}
/**
* An instance is indicated by {@link isDatePeriod}.
*/
export interface ValueDatePeriod extends ValueDateDated {
isDatePeriod: true;
hasPhrase: false;
isDatePunctual: false;
isDateRange: false;
isDateApproximated: false;
isDateInterpreted: false;
}
/**
* An instance is indicated by {@link isDatePeriod} and defined {@link dateFrom}.
*/
export interface ValueDatePeriodFrom extends ValueDatePeriod {
dateFrom: ValuePartDate;
}
/**
* An instance is indicated by {@link isDatePeriod} and defined {@link dateTo}.
*/
export interface ValueDatePeriodTo extends ValueDatePeriod {
dateTo: ValuePartDate;
}
/**
* An instance is indicated by {@link isDatePeriod}, defined {@link dateFrom} and defined {@link dateTo}.
*/
export interface ValueDatePeriodFull extends ValueDatePeriodFrom, ValueDatePeriodTo {
}
/**
* A valid Gedcom date. See {@link ValueDateBase}, the base type for all of them.
*/
export declare type ValueDate = ValueDateNormal | ValueDateApproximated | ValueDatePeriodFrom | ValueDatePeriodTo | ValueDatePeriodFull | ValueDateRangeAfter | ValueDateRangeBefore | ValueDateRangeFull | ValueDateInterpreted | ValueDatePhraseOnly;
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=dates.js.map
@@ -0,0 +1 @@
{"version":3,"file":"dates.js","sourceRoot":"","sources":["../../../../src/parse/value/dates.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
import { ValueExactTime } from './ValueExactTime';
/**
* Parses a time of format hours-minutes, optionally containing seconds and even centiseconds information.
* @param value The value to parse
* @category Value parsers
*/
export declare const parseExactTime: (value: string | null) => ValueExactTime | null;
@@ -0,0 +1,41 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseExactTime = void 0;
/**
* Parses a time of format hours-minutes, optionally containing seconds and even centiseconds information.
* @param value The value to parse
* @category Value parsers
*/
const parseExactTime = (value) => {
// Note: Gedcom 5.5.5 says *no* leading zeros are allowed on hours. For compatibility purposes we *do* accept them anyway
const rTime = /^(0?[0-9]|1[0-9]|2[0-3]):([0-5][0-9])(?::([0-5][0-9])(?:\.([0-9]{2}))?)?$/;
if (!value) {
return null;
}
const groups = rTime.exec(value);
if (!groups) {
return null;
}
const hours = parseInt(groups[1]);
const minutes = parseInt(groups[2]);
const hoursMinutes = {
hours,
minutes,
};
if (groups[3] !== undefined) {
const seconds = parseInt(groups[3]);
const hoursMinutesSeconds = Object.assign(Object.assign({}, hoursMinutes), { seconds });
if (groups[4] !== undefined) {
const centiseconds = parseInt(groups[4]);
return Object.assign(Object.assign({}, hoursMinutesSeconds), { centiseconds });
}
else {
return hoursMinutesSeconds;
}
}
else {
return hoursMinutes;
}
};
exports.parseExactTime = parseExactTime;
//# sourceMappingURL=exacttime.js.map
@@ -0,0 +1 @@
{"version":3,"file":"exacttime.js","sourceRoot":"","sources":["../../../../src/parse/value/exacttime.ts"],"names":[],"mappings":";;;AAEA;;;;GAIG;AACI,MAAM,cAAc,GAAG,CAAC,KAAoB,EAAyB,EAAE;IAC1E,yHAAyH;IACzH,MAAM,KAAK,GAAG,2EAA2E,CAAC;IAE1F,IAAI,CAAC,KAAK,EAAE;QACR,OAAO,IAAI,CAAC;KACf;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACjC,IAAI,CAAC,MAAM,EAAE;QACT,OAAO,IAAI,CAAC;KACf;IACD,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAClC,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACpC,MAAM,YAAY,GAAG;QACjB,KAAK;QACL,OAAO;KACV,CAAC;IACF,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE;QACzB,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACpC,MAAM,mBAAmB,mCAClB,YAAY,KACf,OAAO,GACV,CAAC;QACF,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE;YACzB,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YACzC,uCACO,mBAAmB,KACtB,YAAY,IACd;SACL;aAAM;YACH,OAAO,mBAAmB,CAAC;SAC9B;KACJ;SAAM;QACH,OAAO,YAAY,CAAC;KACvB;AACL,CAAC,CAAC;AAnCW,QAAA,cAAc,kBAmCzB"}
@@ -0,0 +1,28 @@
/**
* @category Parsed values
*/
export { ValueExactDate } from './ValueExactDate';
/**
* @category Parsed values
*/
export { ValueExactTime } from './ValueExactTime';
/**
* @category Parsed values
*/
export { ValueNameParts } from './ValueNameParts';
/**
* @category Parsed values
*/
export { ValueAge } from './ValueAge';
export { parseAge } from './age';
/**
* @category Parsed values
*/
export { ValuePartYear, ValuePartYearNormal, ValuePartYearDual, ValuePartCalendar, ValuePartDateYear, ValuePartDateMonth, ValuePartDateDay, ValuePartDate, ValueDateBase, ValueDatePhrased, ValueDatePhraseOnly, ValueDateDated, ValueDatePunctual, ValueDateApproximated, ValueDateInterpreted, ValueDateNormal, ValueDateRange, ValueDateRangeAfter, ValueDateRangeBefore, ValueDateRangeFull, ValueDatePeriod, ValueDatePeriodFrom, ValueDatePeriodTo, ValueDatePeriodFull, ValueDate, } from './dates';
export { parseDate, parseExactDate } from './date';
export { toJsDate, toJsDateTime } from './datejs';
export { parseLatitude, parseLongitude } from './coordinates';
export { parseExactTime } from './exacttime';
export { parsePlaceParts } from './place';
export { parseNameParts } from './name';
export { parseVersionParts } from './version';
@@ -0,0 +1,23 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseVersionParts = exports.parseNameParts = exports.parsePlaceParts = exports.parseExactTime = exports.parseLongitude = exports.parseLatitude = exports.toJsDateTime = exports.toJsDate = exports.parseExactDate = exports.parseDate = exports.parseAge = void 0;
var age_1 = require("./age");
Object.defineProperty(exports, "parseAge", { enumerable: true, get: function () { return age_1.parseAge; } });
var date_1 = require("./date");
Object.defineProperty(exports, "parseDate", { enumerable: true, get: function () { return date_1.parseDate; } });
Object.defineProperty(exports, "parseExactDate", { enumerable: true, get: function () { return date_1.parseExactDate; } });
var datejs_1 = require("./datejs");
Object.defineProperty(exports, "toJsDate", { enumerable: true, get: function () { return datejs_1.toJsDate; } });
Object.defineProperty(exports, "toJsDateTime", { enumerable: true, get: function () { return datejs_1.toJsDateTime; } });
var coordinates_1 = require("./coordinates");
Object.defineProperty(exports, "parseLatitude", { enumerable: true, get: function () { return coordinates_1.parseLatitude; } });
Object.defineProperty(exports, "parseLongitude", { enumerable: true, get: function () { return coordinates_1.parseLongitude; } });
var exacttime_1 = require("./exacttime");
Object.defineProperty(exports, "parseExactTime", { enumerable: true, get: function () { return exacttime_1.parseExactTime; } });
var place_1 = require("./place");
Object.defineProperty(exports, "parsePlaceParts", { enumerable: true, get: function () { return place_1.parsePlaceParts; } });
var name_1 = require("./name");
Object.defineProperty(exports, "parseNameParts", { enumerable: true, get: function () { return name_1.parseNameParts; } });
var version_1 = require("./version");
Object.defineProperty(exports, "parseVersionParts", { enumerable: true, get: function () { return version_1.parseVersionParts; } });
//# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/parse/value/index.ts"],"names":[],"mappings":";;;AAgBA,6BAAiC;AAAxB,+FAAA,QAAQ,OAAA;AA+BjB,+BAAmD;AAA1C,iGAAA,SAAS,OAAA;AAAE,sGAAA,cAAc,OAAA;AAClC,mCAAkD;AAAzC,kGAAA,QAAQ,OAAA;AAAE,sGAAA,YAAY,OAAA;AAC/B,6CAA8D;AAArD,4GAAA,aAAa,OAAA;AAAE,6GAAA,cAAc,OAAA;AACtC,yCAA6C;AAApC,2GAAA,cAAc,OAAA;AACvB,iCAA0C;AAAjC,wGAAA,eAAe,OAAA;AACxB,+BAAwC;AAA/B,sGAAA,cAAc,OAAA;AACvB,qCAA8C;AAArC,4GAAA,iBAAiB,OAAA"}
@@ -0,0 +1,7 @@
import { ValueNameParts } from './ValueNameParts';
/**
* Parses a name value into three potentially undefined name parts.
* @param value The value to parse
* @category Value parsers
*/
export declare const parseNameParts: (value: string | null) => ValueNameParts | null;
@@ -0,0 +1,27 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseNameParts = void 0;
// eslint-disable-next-line
const rNameParts = /^(?:([^\/]*)|(?:(?:([^\/]*?) ?)?\/([^\/]*)\/(?: ?([^\/]*))?))$/;
/**
* Parses a name value into three potentially undefined name parts.
* @param value The value to parse
* @category Value parsers
*/
const parseNameParts = (value) => {
if (!value) {
return null;
}
const groups = rNameParts.exec(value);
if (!groups) {
return null;
}
if (groups[1] === undefined) {
return [groups[2], groups[3], groups[4]];
}
else {
return [groups[1], undefined, undefined];
}
};
exports.parseNameParts = parseNameParts;
//# sourceMappingURL=name.js.map

Some files were not shown because too many files have changed in this diff Show More