@treeviz/gedcom-parser 2.0.12 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +236 -989
- package/dist/classes/common.d.ts +4 -4
- package/dist/classes/common.d.ts.map +1 -1
- package/dist/classes/date.d.ts +2 -0
- package/dist/classes/date.d.ts.map +1 -1
- package/dist/classes/fam.d.ts +2 -1
- package/dist/classes/fam.d.ts.map +1 -1
- package/dist/classes/fams.d.ts.map +1 -1
- package/dist/classes/gedcom.d.ts +39 -2
- package/dist/classes/gedcom.d.ts.map +1 -1
- package/dist/classes/index.js +1364 -318
- package/dist/classes/indi.d.ts +19 -2
- package/dist/classes/indi.d.ts.map +1 -1
- package/dist/classes/list.d.ts.map +1 -1
- package/dist/classes/note.d.ts.map +1 -1
- package/dist/classes/obje.d.ts +2 -1
- package/dist/classes/obje.d.ts.map +1 -1
- package/dist/cli/index.js +1368 -313
- package/dist/constants/constants.d.ts.map +1 -1
- package/dist/constants/index.js +312 -73
- package/dist/factories/index.js +310 -71
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1547 -288
- package/dist/interfaces/common.d.ts +6 -4
- package/dist/interfaces/common.d.ts.map +1 -1
- package/dist/interfaces/fam.d.ts +3 -0
- package/dist/interfaces/fam.d.ts.map +1 -1
- package/dist/interfaces/gedcom.d.ts +21 -1
- package/dist/interfaces/gedcom.d.ts.map +1 -1
- package/dist/interfaces/indi.d.ts +11 -1
- package/dist/interfaces/indi.d.ts.map +1 -1
- package/dist/kinship-translator/index.js +310 -71
- package/dist/structures/gedcom.d.ts +1 -0
- package/dist/structures/gedcom.d.ts.map +1 -1
- package/dist/types/types.d.ts +22 -4
- package/dist/types/types.d.ts.map +1 -1
- package/dist/utils/common-creator.d.ts.map +1 -1
- package/dist/utils/fact-edit.d.ts +12 -0
- package/dist/utils/fact-edit.d.ts.map +1 -1
- package/dist/utils/family-edit.d.ts +2 -2
- package/dist/utils/family-edit.d.ts.map +1 -1
- package/dist/utils/gedcom-version.d.ts +6 -0
- package/dist/utils/gedcom-version.d.ts.map +1 -0
- package/dist/utils/gedcom7-dates.d.ts +20 -0
- package/dist/utils/gedcom7-dates.d.ts.map +1 -0
- package/dist/utils/gedcom7-enumerations.d.ts +26 -0
- package/dist/utils/gedcom7-enumerations.d.ts.map +1 -0
- package/dist/utils/gedcom7-metadata.d.ts +19 -0
- package/dist/utils/gedcom7-metadata.d.ts.map +1 -0
- package/dist/utils/gedcom7-schema.d.ts +27 -0
- package/dist/utils/gedcom7-schema.d.ts.map +1 -0
- package/dist/utils/gedzip.d.ts +81 -0
- package/dist/utils/gedzip.d.ts.map +1 -0
- package/dist/utils/index.d.ts +9 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1547 -288
- package/dist/utils/local-media.d.ts +30 -0
- package/dist/utils/local-media.d.ts.map +1 -0
- package/dist/utils/media-utils.d.ts +10 -6
- package/dist/utils/media-utils.d.ts.map +1 -1
- package/dist/utils/multimedia.d.ts +38 -0
- package/dist/utils/multimedia.d.ts.map +1 -0
- package/dist/utils/parser.d.ts.map +1 -1
- package/dist/utils/uid.d.ts +6 -0
- package/dist/utils/uid.d.ts.map +1 -0
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { debounce, set, get, uniqBy, unset, difference, intersectionBy, differenceBy } from 'lodash-es';
|
|
2
2
|
import { format, isValid, parse } from 'date-fns';
|
|
3
|
+
import JSZip from 'jszip';
|
|
3
4
|
|
|
4
5
|
var __defProp = Object.defineProperty;
|
|
5
6
|
var __export = (target, all) => {
|
|
@@ -9,8 +10,8 @@ var __export = (target, all) => {
|
|
|
9
10
|
|
|
10
11
|
// src/constants/constants.ts
|
|
11
12
|
var APP_BRANDING = "TreeViz - The Family Tree Visualiser & Editor";
|
|
12
|
-
var REF_LINE_REG = /^0 (?:(@[_a-zA-Z0-9]*@) )?(?<type>_[_A-Z][_a-zA-
|
|
13
|
-
var LINE_REG = /(?<indent>^[0-9]) (?:(@[_a-zA-Z0-9]*@) )?(?<type>_[_A-Z][_a-zA-
|
|
13
|
+
var REF_LINE_REG = /^0 (?:(@[_a-zA-Z0-9]*@) )?(?<type>_[_A-Z][_a-zA-Z0-9]{2,}|_?[A-Z][A-Za-z0-9]{2,}) ?(?<value>.*)/gm;
|
|
14
|
+
var LINE_REG = /(?<indent>^[0-9]{1,2}) (?:(@[_a-zA-Z0-9]*@) )?(?<type>_[_A-Z][_a-zA-Z0-9]{2,}|_?[A-Z][A-Za-z0-9]{2,}) ?(?<value>.*)/;
|
|
14
15
|
var ID_REG = /^@[_a-zA-Z0-9]+@/;
|
|
15
16
|
var ID_GETTER_REG = /^(?<at>@)?(?<letter>[A-Z])?/i;
|
|
16
17
|
var ID_SPLIT_REG = /^@[_a-zA-Z0-9]+@:/;
|
|
@@ -409,11 +410,17 @@ var List = class _List {
|
|
|
409
410
|
const gedcom = [];
|
|
410
411
|
this.entries().forEach(([_, item]) => {
|
|
411
412
|
const validTag = getValidTag(tag);
|
|
412
|
-
const
|
|
413
|
-
const
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
413
|
+
const xref = item.id;
|
|
414
|
+
const payload = item.exportValue?.();
|
|
415
|
+
if (xref) {
|
|
416
|
+
gedcom.push(
|
|
417
|
+
`${level} ${xref} ${validTag}${payload ? ` ${payload}` : ""}`
|
|
418
|
+
);
|
|
419
|
+
} else {
|
|
420
|
+
gedcom.push(
|
|
421
|
+
`${level} ${validTag}${payload ? ` ${payload}` : ""}`
|
|
422
|
+
);
|
|
423
|
+
}
|
|
417
424
|
gedcom.push(
|
|
418
425
|
...item.toGedcomLines(
|
|
419
426
|
validTag,
|
|
@@ -671,12 +678,14 @@ var Common = class _Common {
|
|
|
671
678
|
);
|
|
672
679
|
}
|
|
673
680
|
standardizeObject(tag, options) {
|
|
674
|
-
if (tag === "OBJE" &&
|
|
681
|
+
if (tag === "OBJE" && options?.obje?.standardize && "standardizeMedia" in this) {
|
|
675
682
|
const standardize = this.standardizeMedia;
|
|
676
683
|
return standardize.call(
|
|
677
684
|
this,
|
|
678
685
|
options.obje.namespace,
|
|
679
|
-
options.obje.override
|
|
686
|
+
options.obje.override,
|
|
687
|
+
void 0,
|
|
688
|
+
options.gedcomVersion
|
|
680
689
|
);
|
|
681
690
|
}
|
|
682
691
|
}
|
|
@@ -703,7 +712,7 @@ var Common = class _Common {
|
|
|
703
712
|
if (typeof prop?.toObject === "function") {
|
|
704
713
|
if (prop instanceof _Common) {
|
|
705
714
|
json[validKey] = prop.toObject(validKey, options);
|
|
706
|
-
} else {
|
|
715
|
+
} else if (prop instanceof List) {
|
|
707
716
|
json = {
|
|
708
717
|
...json,
|
|
709
718
|
...prop.toObject(validKey, options)
|
|
@@ -761,8 +770,12 @@ var Common = class _Common {
|
|
|
761
770
|
this.standardizeObject(tag, options);
|
|
762
771
|
const validKeys = getValidKeys(this);
|
|
763
772
|
const gedcom = [];
|
|
773
|
+
const isGedcom7Export = options?.gedcomVersion === "7.0";
|
|
764
774
|
validKeys.forEach((key) => {
|
|
765
775
|
const validKey = key;
|
|
776
|
+
if (isGedcom7Export && validKey === "CONC") {
|
|
777
|
+
return;
|
|
778
|
+
}
|
|
766
779
|
const prop = this.get(validKey);
|
|
767
780
|
if (typeof prop?.toGedcomLines === "function") {
|
|
768
781
|
if (prop instanceof _Common) {
|
|
@@ -773,7 +786,7 @@ var Common = class _Common {
|
|
|
773
786
|
gedcom.push(
|
|
774
787
|
...prop.toGedcomLines(validKey, level + 1, options)
|
|
775
788
|
);
|
|
776
|
-
} else {
|
|
789
|
+
} else if (prop instanceof List) {
|
|
777
790
|
gedcom.push(
|
|
778
791
|
...prop.toGedcomLines(validKey, level, options)
|
|
779
792
|
);
|
|
@@ -2207,6 +2220,81 @@ var getPlaces = (common, type = ["ALL" /* All */], maxLevel = 1, level = 0, main
|
|
|
2207
2220
|
});
|
|
2208
2221
|
return places;
|
|
2209
2222
|
};
|
|
2223
|
+
|
|
2224
|
+
// src/utils/local-media.ts
|
|
2225
|
+
var localMediaResolver;
|
|
2226
|
+
var mediaContentResolver;
|
|
2227
|
+
var setLocalMediaResolver = (resolver) => {
|
|
2228
|
+
localMediaResolver = resolver;
|
|
2229
|
+
};
|
|
2230
|
+
var setMediaContentResolver = (resolver) => {
|
|
2231
|
+
mediaContentResolver = resolver;
|
|
2232
|
+
};
|
|
2233
|
+
var isRemoteOrEmbeddedMediaUrl = (path) => {
|
|
2234
|
+
if (!path) {
|
|
2235
|
+
return false;
|
|
2236
|
+
}
|
|
2237
|
+
return path.startsWith("data:") || path.startsWith("blob:") || /^https?:\/\//i.test(path);
|
|
2238
|
+
};
|
|
2239
|
+
var resolveLocalMediaUrl = async (path) => {
|
|
2240
|
+
if (!path) {
|
|
2241
|
+
return void 0;
|
|
2242
|
+
}
|
|
2243
|
+
if (isRemoteOrEmbeddedMediaUrl(path)) {
|
|
2244
|
+
return path;
|
|
2245
|
+
}
|
|
2246
|
+
const resolved = await localMediaResolver?.(path);
|
|
2247
|
+
return resolved;
|
|
2248
|
+
};
|
|
2249
|
+
var blobToDataUrl = async (blob) => {
|
|
2250
|
+
const buffer = await blob.arrayBuffer();
|
|
2251
|
+
const bytes = new Uint8Array(buffer);
|
|
2252
|
+
const mime = blob.type || "application/octet-stream";
|
|
2253
|
+
if (typeof Buffer !== "undefined") {
|
|
2254
|
+
return `data:${mime};base64,${Buffer.from(bytes).toString("base64")}`;
|
|
2255
|
+
}
|
|
2256
|
+
let binary = "";
|
|
2257
|
+
const chunk = 32768;
|
|
2258
|
+
for (let i = 0; i < bytes.length; i += chunk) {
|
|
2259
|
+
binary += String.fromCharCode(...bytes.subarray(i, i + chunk));
|
|
2260
|
+
}
|
|
2261
|
+
return `data:${mime};base64,${btoa(binary)}`;
|
|
2262
|
+
};
|
|
2263
|
+
var resolveMediaContent = async (media) => {
|
|
2264
|
+
const fromHost = await mediaContentResolver?.(media);
|
|
2265
|
+
if (fromHost?.content) {
|
|
2266
|
+
return fromHost;
|
|
2267
|
+
}
|
|
2268
|
+
const url = media.url;
|
|
2269
|
+
if (!url) {
|
|
2270
|
+
return void 0;
|
|
2271
|
+
}
|
|
2272
|
+
if (url.startsWith("data:") || url.startsWith("blob:")) {
|
|
2273
|
+
return { content: url, contentType: media.contentType };
|
|
2274
|
+
}
|
|
2275
|
+
if (!isRemoteOrEmbeddedMediaUrl(url)) {
|
|
2276
|
+
const local = await resolveLocalMediaUrl(url);
|
|
2277
|
+
if (local && isRemoteOrEmbeddedMediaUrl(local)) {
|
|
2278
|
+
return { content: local, contentType: media.contentType };
|
|
2279
|
+
}
|
|
2280
|
+
return void 0;
|
|
2281
|
+
}
|
|
2282
|
+
if (typeof fetch !== "function") {
|
|
2283
|
+
return void 0;
|
|
2284
|
+
}
|
|
2285
|
+
try {
|
|
2286
|
+
const response = await fetch(url);
|
|
2287
|
+
if (!response.ok) {
|
|
2288
|
+
return void 0;
|
|
2289
|
+
}
|
|
2290
|
+
const blob = await response.blob();
|
|
2291
|
+
const content = await blobToDataUrl(blob);
|
|
2292
|
+
const contentType = media.contentType || blob.type.split("/").pop() || "bin";
|
|
2293
|
+
return { content, contentType };
|
|
2294
|
+
} catch {
|
|
2295
|
+
return void 0;
|
|
2296
|
+
}
|
|
2297
|
+
};
|
|
2210
2298
|
var implemented = (type, ...args) => {
|
|
2211
2299
|
};
|
|
2212
2300
|
var notImplemented = (type, ...args) => {
|
|
@@ -2215,11 +2303,34 @@ var notImplemented = (type, ...args) => {
|
|
|
2215
2303
|
|
|
2216
2304
|
// src/utils/media-utils.ts
|
|
2217
2305
|
var getFileExtension = (filename) => {
|
|
2218
|
-
|
|
2219
|
-
|
|
2306
|
+
if (!filename) {
|
|
2307
|
+
return "";
|
|
2308
|
+
}
|
|
2309
|
+
if (filename.startsWith("data:")) {
|
|
2310
|
+
const mime = filename.slice(5).split(";")[0] || "";
|
|
2311
|
+
const subtype = (mime.split("/")[1] || "").toLowerCase();
|
|
2312
|
+
if (subtype === "jpeg") {
|
|
2313
|
+
return "jpg";
|
|
2314
|
+
}
|
|
2315
|
+
return subtype.split("+")[0] || "";
|
|
2316
|
+
}
|
|
2317
|
+
const withoutQuery = filename.split(/[?#]/)[0] || filename;
|
|
2318
|
+
const match = withoutQuery.match(/\.([^.]+)$/);
|
|
2319
|
+
return match ? match[1].toLowerCase() : "";
|
|
2220
2320
|
};
|
|
2221
2321
|
var isImageFormat = (format2) => {
|
|
2222
|
-
if (!format2)
|
|
2322
|
+
if (!format2) {
|
|
2323
|
+
return false;
|
|
2324
|
+
}
|
|
2325
|
+
let normalized = format2.toLowerCase().trim();
|
|
2326
|
+
if (normalized.startsWith("data:")) {
|
|
2327
|
+
normalized = getFileExtension(normalized);
|
|
2328
|
+
} else if (normalized.includes("/")) {
|
|
2329
|
+
normalized = normalized.split("/")[1]?.split("+")[0] || "";
|
|
2330
|
+
if (normalized === "jpeg") {
|
|
2331
|
+
normalized = "jpg";
|
|
2332
|
+
}
|
|
2333
|
+
}
|
|
2223
2334
|
const imageFormats = [
|
|
2224
2335
|
"jpg",
|
|
2225
2336
|
"jpeg",
|
|
@@ -2231,7 +2342,11 @@ var isImageFormat = (format2) => {
|
|
|
2231
2342
|
"tiff",
|
|
2232
2343
|
"tif"
|
|
2233
2344
|
];
|
|
2234
|
-
return imageFormats.includes(
|
|
2345
|
+
return imageFormats.includes(normalized);
|
|
2346
|
+
};
|
|
2347
|
+
var resolveObjeForm = (obje) => {
|
|
2348
|
+
const value = obje?.get?.("FILE.FORM")?.toValue?.() ?? obje?.get?.("FORM")?.toValue?.();
|
|
2349
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
2235
2350
|
};
|
|
2236
2351
|
|
|
2237
2352
|
// src/factories/place-parser-provider.ts
|
|
@@ -3462,10 +3577,14 @@ var Indi = class extends Common {
|
|
|
3462
3577
|
const clone = obje?.get("_CLON._OID")?.toValue();
|
|
3463
3578
|
const mser = obje?.get("_MSER._LKID")?.toValue();
|
|
3464
3579
|
let url = obje?.get("FILE")?.toValue();
|
|
3465
|
-
const title = obje?.get("TITL")?.toValue() ?? "";
|
|
3466
|
-
const type = obje
|
|
3467
|
-
|
|
3468
|
-
|
|
3580
|
+
const title = obje?.get("FILE.TITL")?.toValue() ?? obje?.get("TITL")?.toValue() ?? "";
|
|
3581
|
+
const type = resolveObjeForm(obje) ?? (url ? getFileExtension(url) : void 0) ?? "raw";
|
|
3582
|
+
let imgId = clone || mser;
|
|
3583
|
+
const hasEmbeddedOrLocalFile = !!url && (url.startsWith("data:") || url.startsWith("blob:") || !/^https?:\/\//i.test(url));
|
|
3584
|
+
if (!hasEmbeddedOrLocalFile && (!www || !tree || !this.id)) {
|
|
3585
|
+
return;
|
|
3586
|
+
}
|
|
3587
|
+
if (!this.id) {
|
|
3469
3588
|
return;
|
|
3470
3589
|
}
|
|
3471
3590
|
if (!namespace && !url) {
|
|
@@ -3483,13 +3602,16 @@ var Indi = class extends Common {
|
|
|
3483
3602
|
}
|
|
3484
3603
|
url = url || `https://${www}/mediaui-viewer/tree/${tree}/media/${media}`;
|
|
3485
3604
|
}
|
|
3605
|
+
if (!imgId && hasEmbeddedOrLocalFile && url) {
|
|
3606
|
+
imgId = typeof media === "string" && media || `local-${String(key).replace(/[@]/g, "")}-${getFileExtension(url) || "bin"}`;
|
|
3607
|
+
}
|
|
3486
3608
|
if (url && imgId) {
|
|
3487
|
-
const id = `${tree}-${this.id}-${imgId}`;
|
|
3609
|
+
const id = `${tree || "gedzip"}-${this.id}-${imgId}`;
|
|
3488
3610
|
list[id] = {
|
|
3489
3611
|
key,
|
|
3490
3612
|
isPrimary,
|
|
3491
3613
|
id,
|
|
3492
|
-
tree,
|
|
3614
|
+
tree: tree || "gedzip",
|
|
3493
3615
|
imgId,
|
|
3494
3616
|
person: this.id,
|
|
3495
3617
|
title,
|
|
@@ -3535,9 +3657,11 @@ var Indi = class extends Common {
|
|
|
3535
3657
|
obje.standardizeMedia();
|
|
3536
3658
|
const isPrimary = obje?.get("_PRIM")?.toValue() === "Y";
|
|
3537
3659
|
const url = obje?.get("FILE")?.toValue();
|
|
3538
|
-
const title = obje?.get("NOTE")?.toValue() ?? "";
|
|
3539
|
-
const type = obje
|
|
3540
|
-
const
|
|
3660
|
+
const title = obje?.get("FILE.NOTE")?.toValue() ?? obje?.get("NOTE")?.toValue() ?? "";
|
|
3661
|
+
const type = resolveObjeForm(obje) ?? (url ? getFileExtension(url) : void 0) ?? "raw";
|
|
3662
|
+
const photoRin = obje?.get("_PHOTO_RIN")?.toValue();
|
|
3663
|
+
const hasEmbeddedOrLocalFile = !!url && (url.startsWith("data:") || url.startsWith("blob:") || !/^https?:\/\//i.test(url));
|
|
3664
|
+
const imgId = photoRin || (hasEmbeddedOrLocalFile && url ? `local-${String(key).replace(/[@]/g, "")}-${getFileExtension(url) || "bin"}` : void 0);
|
|
3541
3665
|
if (url && imgId) {
|
|
3542
3666
|
const id = `${tree}-${this.id}-${imgId}`;
|
|
3543
3667
|
list[id] = {
|
|
@@ -3660,10 +3784,10 @@ var Indi = class extends Common {
|
|
|
3660
3784
|
const isPrimary = obje?.get("_PRIM")?.toValue() === "Y";
|
|
3661
3785
|
const url = obje?.get("FILE")?.toValue();
|
|
3662
3786
|
const title = obje?.get("TITL")?.toValue() ?? "";
|
|
3663
|
-
const type = obje
|
|
3787
|
+
const type = resolveObjeForm(obje) ?? (url ? getFileExtension(url) : void 0) ?? "raw";
|
|
3664
3788
|
if (url) {
|
|
3665
3789
|
const urlMatch = url.match(/\/([^/]+)\?hash=/);
|
|
3666
|
-
const imgId = urlMatch?.[1] || `img-${index}-${Date.now().toString(36)}
|
|
3790
|
+
const imgId = urlMatch?.[1] || (url.startsWith("data:") ? `data-${index}-${getFileExtension(url) || "bin"}` : `img-${index}-${Date.now().toString(36)}`);
|
|
3667
3791
|
const id = `geni-${geniId}-${imgId}`;
|
|
3668
3792
|
list[id] = {
|
|
3669
3793
|
isPrimary,
|
|
@@ -3700,10 +3824,10 @@ var Indi = class extends Common {
|
|
|
3700
3824
|
obje.standardizeMedia();
|
|
3701
3825
|
const isPrimary = obje?.get("_PRIM")?.toValue() === "Y";
|
|
3702
3826
|
const url = obje?.get("FILE")?.toValue();
|
|
3703
|
-
const title = obje?.get("TITL")?.toValue() ?? "";
|
|
3704
|
-
const type = obje
|
|
3827
|
+
const title = obje?.get("FILE.TITL")?.toValue() ?? obje?.get("TITL")?.toValue() ?? "";
|
|
3828
|
+
const type = resolveObjeForm(obje) ?? (url ? getFileExtension(url) : void 0) ?? "raw";
|
|
3705
3829
|
if (url) {
|
|
3706
|
-
const imgId = `media-${index}-${url.split("/").pop()?.split("?")[0]?.substring(0, 20) || Date.now().toString(36)}`;
|
|
3830
|
+
const imgId = `media-${index}-${url.startsWith("data:") ? getFileExtension(url) || "bin" : url.split("/").pop()?.split("?")[0]?.substring(0, 20) || Date.now().toString(36)}`;
|
|
3707
3831
|
const id = `${treeId}-${this.id}-${imgId}`;
|
|
3708
3832
|
list[id] = {
|
|
3709
3833
|
isPrimary,
|
|
@@ -3743,7 +3867,20 @@ var Indi = class extends Common {
|
|
|
3743
3867
|
cacheKey
|
|
3744
3868
|
);
|
|
3745
3869
|
if (cached !== void 0) {
|
|
3746
|
-
|
|
3870
|
+
if (cached?.file && !isRemoteOrEmbeddedMediaUrl(cached.file)) {
|
|
3871
|
+
const resolvedCached = await resolveLocalMediaUrl(cached.file);
|
|
3872
|
+
if (resolvedCached && isRemoteOrEmbeddedMediaUrl(resolvedCached)) {
|
|
3873
|
+
const refreshed = { ...cached, file: resolvedCached };
|
|
3874
|
+
profilePictureCache(
|
|
3875
|
+
this._gedcom,
|
|
3876
|
+
cacheKey,
|
|
3877
|
+
refreshed
|
|
3878
|
+
);
|
|
3879
|
+
return refreshed;
|
|
3880
|
+
}
|
|
3881
|
+
} else {
|
|
3882
|
+
return cached;
|
|
3883
|
+
}
|
|
3747
3884
|
}
|
|
3748
3885
|
const mediaList = await this.multimedia(namespace);
|
|
3749
3886
|
if (!mediaList) {
|
|
@@ -3755,39 +3892,40 @@ var Indi = class extends Common {
|
|
|
3755
3892
|
return void 0;
|
|
3756
3893
|
}
|
|
3757
3894
|
const mediaArray = Object.values(mediaList);
|
|
3758
|
-
const
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3895
|
+
const toDisplayableProfile = async (media, isPrimary) => {
|
|
3896
|
+
const resolvedFile = await resolveLocalMediaUrl(media.url);
|
|
3897
|
+
if (!resolvedFile || !isRemoteOrEmbeddedMediaUrl(resolvedFile)) {
|
|
3898
|
+
return void 0;
|
|
3899
|
+
}
|
|
3900
|
+
return {
|
|
3901
|
+
file: resolvedFile,
|
|
3902
|
+
form: media.contentType,
|
|
3903
|
+
title: media.title,
|
|
3904
|
+
isPrimary
|
|
3767
3905
|
};
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
this._gedcom,
|
|
3774
|
-
cacheKey,
|
|
3775
|
-
void 0
|
|
3776
|
-
);
|
|
3777
|
-
return void 0;
|
|
3778
|
-
}
|
|
3779
|
-
const secondaryMedia = mediaArray.find(
|
|
3780
|
-
(media) => isImageFormat(media.contentType || getFileExtension(media.url))
|
|
3906
|
+
};
|
|
3907
|
+
const candidates = mediaArray.filter(
|
|
3908
|
+
(media) => isImageFormat(
|
|
3909
|
+
media.contentType || media.url || getFileExtension(media.url)
|
|
3910
|
+
)
|
|
3781
3911
|
);
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
|
|
3790
|
-
|
|
3912
|
+
const ordered = [
|
|
3913
|
+
...candidates.filter((media) => media.isPrimary),
|
|
3914
|
+
...candidates.filter((media) => !media.isPrimary)
|
|
3915
|
+
];
|
|
3916
|
+
for (const media of ordered) {
|
|
3917
|
+
if (onlyPrimary && !media.isPrimary) {
|
|
3918
|
+
break;
|
|
3919
|
+
}
|
|
3920
|
+
const result = await toDisplayableProfile(media, !!media.isPrimary);
|
|
3921
|
+
if (result) {
|
|
3922
|
+
profilePictureCache(
|
|
3923
|
+
this._gedcom,
|
|
3924
|
+
cacheKey,
|
|
3925
|
+
result
|
|
3926
|
+
);
|
|
3927
|
+
return result;
|
|
3928
|
+
}
|
|
3791
3929
|
}
|
|
3792
3930
|
profilePictureCache(
|
|
3793
3931
|
this._gedcom,
|
|
@@ -4073,9 +4211,108 @@ var Indi = class extends Common {
|
|
|
4073
4211
|
addParent(parent, pedigree) {
|
|
4074
4212
|
return parent.addChild(this, pedigree);
|
|
4075
4213
|
}
|
|
4214
|
+
/**
|
|
4215
|
+
* Link an existing top-level OBJE record to this individual (`1 OBJE @On@`).
|
|
4216
|
+
*/
|
|
4217
|
+
attachMultimedia(objeOrKey, options) {
|
|
4218
|
+
if (!this._gedcom || !this.id) {
|
|
4219
|
+
return void 0;
|
|
4220
|
+
}
|
|
4221
|
+
const obje = typeof objeOrKey === "string" ? this._gedcom.obje(objeOrKey) : objeOrKey;
|
|
4222
|
+
if (!obje?.id) {
|
|
4223
|
+
return void 0;
|
|
4224
|
+
}
|
|
4225
|
+
const already = this.get("OBJE")?.toList()?.values()?.some((item) => item?.toValue?.() === obje.id);
|
|
4226
|
+
if (!already) {
|
|
4227
|
+
const pointer = makePointer(
|
|
4228
|
+
this._gedcom,
|
|
4229
|
+
this,
|
|
4230
|
+
obje.id,
|
|
4231
|
+
"OBJE"
|
|
4232
|
+
);
|
|
4233
|
+
this.assign("OBJE", pointer);
|
|
4234
|
+
}
|
|
4235
|
+
if (options?.primary) {
|
|
4236
|
+
this.get("OBJE")?.toList()?.forEach((item) => {
|
|
4237
|
+
const target = item?.refType === "OBJE" ? this._gedcom?.obje(
|
|
4238
|
+
String(item.toValue())
|
|
4239
|
+
) : item;
|
|
4240
|
+
if (!target) {
|
|
4241
|
+
return;
|
|
4242
|
+
}
|
|
4243
|
+
if (target.id === obje.id) {
|
|
4244
|
+
target.set("_PRIM", "Y");
|
|
4245
|
+
} else if (target.get("_PRIM")?.toValue() === "Y") {
|
|
4246
|
+
target.set("_PRIM", "N");
|
|
4247
|
+
}
|
|
4248
|
+
});
|
|
4249
|
+
obje.set("_PRIM", "Y");
|
|
4250
|
+
}
|
|
4251
|
+
return obje;
|
|
4252
|
+
}
|
|
4253
|
+
detachMultimedia(objeKey) {
|
|
4254
|
+
const list = this.get("OBJE")?.toList();
|
|
4255
|
+
if (!list) {
|
|
4256
|
+
return;
|
|
4257
|
+
}
|
|
4258
|
+
const toRemove = list.values().filter(
|
|
4259
|
+
(item) => item?.toValue?.() === objeKey || item?.id === objeKey
|
|
4260
|
+
);
|
|
4261
|
+
toRemove.forEach((item) => {
|
|
4262
|
+
if (item) {
|
|
4263
|
+
list.delete(item);
|
|
4264
|
+
}
|
|
4265
|
+
});
|
|
4266
|
+
if (list.length === 0) {
|
|
4267
|
+
this.remove("OBJE");
|
|
4268
|
+
}
|
|
4269
|
+
}
|
|
4270
|
+
/**
|
|
4271
|
+
* Create a multimedia record and attach it to this person.
|
|
4272
|
+
*/
|
|
4273
|
+
attachMediaFromUrl(url, options) {
|
|
4274
|
+
if (!this._gedcom || !url) {
|
|
4275
|
+
return void 0;
|
|
4276
|
+
}
|
|
4277
|
+
const obje = this._gedcom.createMultimediaRecord({
|
|
4278
|
+
file: url,
|
|
4279
|
+
form: options?.form,
|
|
4280
|
+
title: options?.title,
|
|
4281
|
+
mediType: options?.mediType,
|
|
4282
|
+
primary: options?.primary,
|
|
4283
|
+
gedcomVersion: options?.gedcomVersion
|
|
4284
|
+
});
|
|
4285
|
+
return this.attachMultimedia(obje, { primary: options?.primary });
|
|
4286
|
+
}
|
|
4287
|
+
/**
|
|
4288
|
+
* Link a shared SNOTE record via `1 NOTE @Nn@` (GEDCOM 7).
|
|
4289
|
+
*/
|
|
4290
|
+
attachSharedNote(noteOrKey) {
|
|
4291
|
+
if (!this._gedcom || !this.id) {
|
|
4292
|
+
return void 0;
|
|
4293
|
+
}
|
|
4294
|
+
const note = typeof noteOrKey === "string" ? this._gedcom.snote(noteOrKey) : noteOrKey;
|
|
4295
|
+
if (!note?.id) {
|
|
4296
|
+
return void 0;
|
|
4297
|
+
}
|
|
4298
|
+
const already = this.get("NOTE")?.toList()?.values()?.some((item) => item?.toValue?.() === note.id);
|
|
4299
|
+
if (!already) {
|
|
4300
|
+
const pointer = makePointer(
|
|
4301
|
+
this._gedcom,
|
|
4302
|
+
this,
|
|
4303
|
+
note.id,
|
|
4304
|
+
"SNOTE"
|
|
4305
|
+
);
|
|
4306
|
+
this.assign("NOTE", pointer);
|
|
4307
|
+
}
|
|
4308
|
+
return note;
|
|
4309
|
+
}
|
|
4076
4310
|
addFact(input) {
|
|
4077
4311
|
return addIndividualFact(this, input);
|
|
4078
4312
|
}
|
|
4313
|
+
addNonEvent(input) {
|
|
4314
|
+
return addNonEvent(this, input);
|
|
4315
|
+
}
|
|
4079
4316
|
getParentType(id) {
|
|
4080
4317
|
let indi;
|
|
4081
4318
|
if (typeof id === "string" || typeof id === "number") {
|
|
@@ -4116,7 +4353,7 @@ var Indi = class extends Common {
|
|
|
4116
4353
|
if (!famChild) {
|
|
4117
4354
|
const childIndi = this._gedcom?.indi(child.id);
|
|
4118
4355
|
const childState = childIndi?.get("FAMC")?.toList()?.filter((item) => item.value === family.id).index(0);
|
|
4119
|
-
childType = childState?.get("PEDI")?.toValue() || "biological" /* BIOLOGICAL */;
|
|
4356
|
+
childType = (childState?.get("PEDI") ?? childState?.get("PEDT"))?.toValue() || "biological" /* BIOLOGICAL */;
|
|
4120
4357
|
} else {
|
|
4121
4358
|
childType = famChild.get(usedRel)?.toValue() || "biological" /* BIOLOGICAL */;
|
|
4122
4359
|
}
|
|
@@ -4677,7 +4914,7 @@ var Indi = class extends Common {
|
|
|
4677
4914
|
return;
|
|
4678
4915
|
}
|
|
4679
4916
|
const childState = child?.get("FAMC")?.toList()?.filter((item) => item.value === family.id).index(0);
|
|
4680
|
-
const childType = childState?.get("PEDI")?.toValue() || "biological" /* BIOLOGICAL */;
|
|
4917
|
+
const childType = (childState?.get("PEDI") ?? childState?.get("PEDT"))?.toValue() || "biological" /* BIOLOGICAL */;
|
|
4681
4918
|
if (childType?.toLowerCase() === filter.PEDI.toLowerCase()) {
|
|
4682
4919
|
children.append(child);
|
|
4683
4920
|
}
|
|
@@ -4785,7 +5022,7 @@ var Indi = class extends Common {
|
|
|
4785
5022
|
const child = this.id && family.CHIL?.toValueList()?.item(this.id);
|
|
4786
5023
|
if (!child) {
|
|
4787
5024
|
const childState = this?.get("FAMC")?.toList()?.filter((item) => item.value === family.id).index(0);
|
|
4788
|
-
const parentType = childState?.get("PEDI")?.toValue() || "biological" /* BIOLOGICAL */;
|
|
5025
|
+
const parentType = (childState?.get("PEDI") ?? childState?.get("PEDT"))?.toValue() || "biological" /* BIOLOGICAL */;
|
|
4789
5026
|
if (parentType?.toLowerCase() === filter.PEDI.toLowerCase()) {
|
|
4790
5027
|
parents.merge(family.getParents());
|
|
4791
5028
|
}
|
|
@@ -7192,7 +7429,11 @@ var STANDARD_QUALIFIERS = {
|
|
|
7192
7429
|
BEF: "Bef.",
|
|
7193
7430
|
BEFORE: "Bef.",
|
|
7194
7431
|
AFT: "Aft.",
|
|
7195
|
-
AFTER: "Aft."
|
|
7432
|
+
AFTER: "Aft.",
|
|
7433
|
+
CAL: "Abt.",
|
|
7434
|
+
// calculated ≈ about for display
|
|
7435
|
+
EST: "Abt."
|
|
7436
|
+
// estimated ≈ about for display
|
|
7196
7437
|
};
|
|
7197
7438
|
var EXPORT_QUALIFIERS = {
|
|
7198
7439
|
"Abt.": "ABT",
|
|
@@ -7200,6 +7441,11 @@ var EXPORT_QUALIFIERS = {
|
|
|
7200
7441
|
"Aft.": "AFT"
|
|
7201
7442
|
};
|
|
7202
7443
|
var GEDCOM_MONTHS = /\b(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\b/g;
|
|
7444
|
+
var CALENDAR_PREFIX = /^(?<calendar>GREGORIAN|JULIAN|FRENCH_R|HEBREW)\b\s+/i;
|
|
7445
|
+
var isGedcomDateValueForm = (value) => (
|
|
7446
|
+
// Require space/end after the token so display forms like "Abt." are not opaque.
|
|
7447
|
+
/^(FROM|TO|BET|AFT|BEF|ABT|CAL|EST|INT)(\s|$)/i.test(value) || /\bAND\b/i.test(value)
|
|
7448
|
+
);
|
|
7203
7449
|
var NOTE_MARKER = "####";
|
|
7204
7450
|
var formatDateWithComponents = (date, hasDay, hasMonth, hasYear, noteValue, baseFormat = "dd MMM yyyy", locale) => {
|
|
7205
7451
|
const hasNote = baseFormat.includes("NOTE");
|
|
@@ -7224,29 +7470,45 @@ var CommonDate = class extends Common {
|
|
|
7224
7470
|
super(gedcom, id, main, parent);
|
|
7225
7471
|
delete this.id;
|
|
7226
7472
|
}
|
|
7473
|
+
get calendar() {
|
|
7474
|
+
return this._calendar;
|
|
7475
|
+
}
|
|
7227
7476
|
set value(value) {
|
|
7228
7477
|
if (value) {
|
|
7229
|
-
const noteRegExp = /^(?<note>[a-zA-Z]+\.)/;
|
|
7230
|
-
const noteMatch = value.match(noteRegExp)?.groups;
|
|
7231
7478
|
let validValue = value;
|
|
7479
|
+
const calendarMatch = validValue.match(CALENDAR_PREFIX);
|
|
7480
|
+
if (calendarMatch?.groups?.calendar) {
|
|
7481
|
+
this._calendar = calendarMatch.groups.calendar.toUpperCase();
|
|
7482
|
+
validValue = validValue.slice(calendarMatch[0].length);
|
|
7483
|
+
} else {
|
|
7484
|
+
this._calendar = void 0;
|
|
7485
|
+
}
|
|
7486
|
+
const noteRegExp = /^(?<note>[a-zA-Z]+\.)/;
|
|
7487
|
+
const noteMatch = validValue.match(noteRegExp)?.groups;
|
|
7232
7488
|
if (noteMatch?.note) {
|
|
7233
7489
|
this.NOTE = this.NOTE || createCommon(this._gedcom, void 0, this.main);
|
|
7234
7490
|
this.NOTE.value = noteMatch?.note;
|
|
7235
|
-
validValue =
|
|
7491
|
+
validValue = validValue.replace(noteRegExp, "");
|
|
7236
7492
|
} else {
|
|
7237
|
-
const qualifierMatch =
|
|
7238
|
-
/^(?<qualifier>ABT|ABOUT|BEF|BEFORE|AFT|AFTER)\b\s*/i
|
|
7493
|
+
const qualifierMatch = validValue.match(
|
|
7494
|
+
/^(?<qualifier>ABT|ABOUT|BEF|BEFORE|AFT|AFTER|CAL|EST)\b\s*/i
|
|
7239
7495
|
);
|
|
7240
7496
|
const qualifier = qualifierMatch?.groups?.qualifier?.toUpperCase();
|
|
7241
7497
|
const note = qualifier ? STANDARD_QUALIFIERS[qualifier] : void 0;
|
|
7242
7498
|
if (note) {
|
|
7243
7499
|
this.NOTE = this.NOTE || createCommon(this._gedcom, void 0, this.main);
|
|
7244
7500
|
this.NOTE.value = note;
|
|
7245
|
-
validValue =
|
|
7501
|
+
validValue = validValue.slice(qualifierMatch[0].length);
|
|
7246
7502
|
}
|
|
7247
7503
|
}
|
|
7248
7504
|
const acceptedDate = this.isValidDateFormat(validValue);
|
|
7249
|
-
if (
|
|
7505
|
+
if (isGedcomDateValueForm(validValue.trim())) {
|
|
7506
|
+
delete this.DAY;
|
|
7507
|
+
delete this.MONTH;
|
|
7508
|
+
delete this.YEAR;
|
|
7509
|
+
this._date = void 0;
|
|
7510
|
+
this._value = value;
|
|
7511
|
+
} else if (acceptedDate) {
|
|
7250
7512
|
this.DAY = this.DAY || createCommon(this._gedcom, void 0, this.main);
|
|
7251
7513
|
this.DAY.value = format(acceptedDate, "dd");
|
|
7252
7514
|
this.MONTH = this.MONTH || createCommon(this._gedcom, void 0, this.main);
|
|
@@ -7349,6 +7611,15 @@ var CommonDate = class extends Common {
|
|
|
7349
7611
|
);
|
|
7350
7612
|
}
|
|
7351
7613
|
exportValue() {
|
|
7614
|
+
if (typeof this._value === "string") {
|
|
7615
|
+
const withoutCalendar = this._value.replace(CALENDAR_PREFIX, "");
|
|
7616
|
+
if (isGedcomDateValueForm(withoutCalendar.trim())) {
|
|
7617
|
+
return this._value.replace(
|
|
7618
|
+
/^((?:GREGORIAN|JULIAN|FRENCH_R|HEBREW)\s+)?(FROM|TO|BET|AFT|BEF|ABT|CAL|EST|INT)\b/i,
|
|
7619
|
+
(_m, cal, q) => `${cal || ""}${q.toUpperCase()}`
|
|
7620
|
+
);
|
|
7621
|
+
}
|
|
7622
|
+
}
|
|
7352
7623
|
const formatted = this.toValue("NOTE dd MMM yyyy", null);
|
|
7353
7624
|
if (!formatted) {
|
|
7354
7625
|
return formatted;
|
|
@@ -7356,10 +7627,14 @@ var CommonDate = class extends Common {
|
|
|
7356
7627
|
const note = this.NOTE?.value?.trim();
|
|
7357
7628
|
const qualifier = note ? EXPORT_QUALIFIERS[note] : void 0;
|
|
7358
7629
|
const standardized = qualifier ? formatted.replace(note, qualifier) : formatted;
|
|
7359
|
-
|
|
7630
|
+
const withMonths = standardized.replace(
|
|
7360
7631
|
GEDCOM_MONTHS,
|
|
7361
7632
|
(month) => month.toUpperCase()
|
|
7362
7633
|
);
|
|
7634
|
+
if (this._calendar && this._calendar !== "GREGORIAN") {
|
|
7635
|
+
return `${this._calendar} ${withMonths}`;
|
|
7636
|
+
}
|
|
7637
|
+
return withMonths;
|
|
7363
7638
|
}
|
|
7364
7639
|
toGedcomLines(tag, level = 0, options) {
|
|
7365
7640
|
const internal = new RegExp(
|
|
@@ -7535,6 +7810,24 @@ var setDeceased = (indi, deceased) => {
|
|
|
7535
7810
|
}
|
|
7536
7811
|
addIndividualFact(indi, { tag: "DEAT", value: "Y" });
|
|
7537
7812
|
};
|
|
7813
|
+
var addNonEvent = (owner, input) => {
|
|
7814
|
+
const gedcom = owner.getGedcom();
|
|
7815
|
+
const eventType = input.event?.trim().toUpperCase();
|
|
7816
|
+
if (!gedcom || !eventType) {
|
|
7817
|
+
return void 0;
|
|
7818
|
+
}
|
|
7819
|
+
const no = createCommon(gedcom, void 0, owner);
|
|
7820
|
+
no.type = "NO";
|
|
7821
|
+
no.value = eventType;
|
|
7822
|
+
if (input.date?.trim()) {
|
|
7823
|
+
setDateOn(gedcom, owner, no, input.date);
|
|
7824
|
+
}
|
|
7825
|
+
if (input.note?.trim()) {
|
|
7826
|
+
no.set("NOTE", input.note.trim());
|
|
7827
|
+
}
|
|
7828
|
+
owner.assign("NO", no);
|
|
7829
|
+
return no;
|
|
7830
|
+
};
|
|
7538
7831
|
|
|
7539
7832
|
// src/classes/fam.ts
|
|
7540
7833
|
var Fam = class extends Common {
|
|
@@ -7586,6 +7879,9 @@ var Fam = class extends Common {
|
|
|
7586
7879
|
addFact(input) {
|
|
7587
7880
|
return addFamilyFact(this, input);
|
|
7588
7881
|
}
|
|
7882
|
+
addNonEvent(input) {
|
|
7883
|
+
return addNonEvent(this, input);
|
|
7884
|
+
}
|
|
7589
7885
|
toList() {
|
|
7590
7886
|
return new Families().concat(
|
|
7591
7887
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -7639,70 +7935,965 @@ var Families = class _Families extends List {
|
|
|
7639
7935
|
}
|
|
7640
7936
|
};
|
|
7641
7937
|
|
|
7642
|
-
//
|
|
7643
|
-
var
|
|
7644
|
-
|
|
7645
|
-
|
|
7646
|
-
|
|
7647
|
-
|
|
7648
|
-
|
|
7649
|
-
|
|
7938
|
+
// src/utils/gedcom-version.ts
|
|
7939
|
+
var GEDCOM_EXPORT_VERSIONS = ["5.5.1", "7.0"];
|
|
7940
|
+
var DEFAULT_GEDCOM_EXPORT_VERSION = "5.5.1";
|
|
7941
|
+
var normalizeGedcomVersion = (value) => {
|
|
7942
|
+
const trimmed = value?.trim() ?? "";
|
|
7943
|
+
if (trimmed.startsWith("7")) {
|
|
7944
|
+
return "7.0";
|
|
7945
|
+
}
|
|
7946
|
+
return "5.5.1";
|
|
7947
|
+
};
|
|
7948
|
+
var isGedcom7 = (value) => normalizeGedcomVersion(value) === "7.0";
|
|
7949
|
+
var GEDZIP_MIME = "application/vnd.familysearch.gedcom+zip";
|
|
7950
|
+
var GEDZIP_EXTENSION = "gdz";
|
|
7951
|
+
var GEDZIP_GEDCOM_ENTRY = "gedcom.ged";
|
|
7952
|
+
var sanitizePathSegment = (name) => name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^\.+/, "") || "file";
|
|
7953
|
+
var extensionFor = (contentType) => {
|
|
7954
|
+
const raw = (contentType || "bin").replace(/^\./, "").toLowerCase();
|
|
7955
|
+
if (raw.includes("/")) {
|
|
7956
|
+
return raw.split("/").pop() || "bin";
|
|
7957
|
+
}
|
|
7958
|
+
return raw || "bin";
|
|
7959
|
+
};
|
|
7960
|
+
var rewriteGedcomFilePaths = (gedcomText, urlToPath) => {
|
|
7961
|
+
const entries = urlToPath instanceof Map ? urlToPath : new Map(Object.entries(urlToPath));
|
|
7962
|
+
let text = gedcomText;
|
|
7963
|
+
entries.forEach((path, url) => {
|
|
7964
|
+
const escaped = url.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
7965
|
+
text = text.replace(
|
|
7966
|
+
new RegExp(`(^|\\r?\\n)(\\d+ FILE )${escaped}`, "g"),
|
|
7967
|
+
`$1$2${path}`
|
|
7968
|
+
);
|
|
7969
|
+
});
|
|
7970
|
+
return text;
|
|
7971
|
+
};
|
|
7972
|
+
var assignMediaPaths = (mediaFiles) => {
|
|
7973
|
+
const urlToPath = /* @__PURE__ */ new Map();
|
|
7974
|
+
const usedPaths = /* @__PURE__ */ new Set([GEDZIP_GEDCOM_ENTRY]);
|
|
7975
|
+
const files = [];
|
|
7976
|
+
for (const file of mediaFiles) {
|
|
7977
|
+
if (!file.content || !file.url) {
|
|
7978
|
+
continue;
|
|
7979
|
+
}
|
|
7980
|
+
const ext = extensionFor(file.contentType);
|
|
7981
|
+
const base = sanitizePathSegment(
|
|
7982
|
+
file.imgId || file.title || file.id || "media"
|
|
7983
|
+
);
|
|
7984
|
+
let path = `media/${base}.${ext}`;
|
|
7985
|
+
let suffix = 1;
|
|
7986
|
+
while (usedPaths.has(path)) {
|
|
7987
|
+
path = `media/${base}-${suffix++}.${ext}`;
|
|
7988
|
+
}
|
|
7989
|
+
usedPaths.add(path);
|
|
7990
|
+
urlToPath.set(file.url, path);
|
|
7991
|
+
const marker = "base64,";
|
|
7992
|
+
const idx = file.content.indexOf(marker);
|
|
7993
|
+
if (idx >= 0) {
|
|
7994
|
+
files.push({
|
|
7995
|
+
path,
|
|
7996
|
+
url: file.url,
|
|
7997
|
+
content: file.content.substring(idx + marker.length),
|
|
7998
|
+
base64: true
|
|
7999
|
+
});
|
|
8000
|
+
} else {
|
|
8001
|
+
files.push({
|
|
8002
|
+
path,
|
|
8003
|
+
url: file.url,
|
|
8004
|
+
content: file.content,
|
|
8005
|
+
base64: false
|
|
8006
|
+
});
|
|
8007
|
+
}
|
|
8008
|
+
}
|
|
8009
|
+
return { urlToPath, files };
|
|
8010
|
+
};
|
|
8011
|
+
var buildGedzip = async (gedcomText, mediaFiles = []) => {
|
|
8012
|
+
const zip = new JSZip();
|
|
8013
|
+
const { urlToPath, files } = assignMediaPaths(mediaFiles);
|
|
8014
|
+
for (const file of files) {
|
|
8015
|
+
zip.file(file.path, file.content, { base64: file.base64 });
|
|
8016
|
+
}
|
|
8017
|
+
zip.file(GEDZIP_GEDCOM_ENTRY, rewriteGedcomFilePaths(gedcomText, urlToPath));
|
|
8018
|
+
return zip.generateAsync({ type: "uint8array" });
|
|
8019
|
+
};
|
|
8020
|
+
var normalizeZipPath = (name) => name.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
8021
|
+
var MIME_BY_EXT = {
|
|
8022
|
+
jpg: "image/jpeg",
|
|
8023
|
+
jpeg: "image/jpeg",
|
|
8024
|
+
png: "image/png",
|
|
8025
|
+
gif: "image/gif",
|
|
8026
|
+
webp: "image/webp",
|
|
8027
|
+
bmp: "image/bmp",
|
|
8028
|
+
tif: "image/tiff",
|
|
8029
|
+
tiff: "image/tiff",
|
|
8030
|
+
svg: "image/svg+xml",
|
|
8031
|
+
pdf: "application/pdf"
|
|
8032
|
+
};
|
|
8033
|
+
var mimeForPath = (path) => {
|
|
8034
|
+
const ext = (path.split(".").pop() || "").toLowerCase();
|
|
8035
|
+
return MIME_BY_EXT[ext] || "application/octet-stream";
|
|
8036
|
+
};
|
|
8037
|
+
var bytesToBase64 = (bytes) => {
|
|
8038
|
+
if (typeof Buffer !== "undefined") {
|
|
8039
|
+
return Buffer.from(bytes).toString("base64");
|
|
8040
|
+
}
|
|
8041
|
+
let binary = "";
|
|
8042
|
+
const chunk = 32768;
|
|
8043
|
+
for (let i = 0; i < bytes.length; i += chunk) {
|
|
8044
|
+
binary += String.fromCharCode(...bytes.subarray(i, i + chunk));
|
|
8045
|
+
}
|
|
8046
|
+
return btoa(binary);
|
|
8047
|
+
};
|
|
8048
|
+
var bytesToDataUrl = (bytes, mime) => `data:${mime};base64,${bytesToBase64(bytes)}`;
|
|
8049
|
+
var remountGedzipMediaAsDataUrls = (extracted) => {
|
|
8050
|
+
if (!extracted.mediaEntries.length) {
|
|
8051
|
+
return extracted.gedcomText;
|
|
8052
|
+
}
|
|
8053
|
+
const pathToDataUrl = /* @__PURE__ */ new Map();
|
|
8054
|
+
for (const media of extracted.mediaEntries) {
|
|
8055
|
+
const path = normalizeZipPath(media.path);
|
|
8056
|
+
const dataUrl = bytesToDataUrl(media.content, mimeForPath(path));
|
|
8057
|
+
pathToDataUrl.set(path, dataUrl);
|
|
8058
|
+
pathToDataUrl.set(`./${path}`, dataUrl);
|
|
8059
|
+
const base = path.split("/").pop();
|
|
8060
|
+
if (base) {
|
|
8061
|
+
pathToDataUrl.set(base, dataUrl);
|
|
8062
|
+
pathToDataUrl.set(`media/${base}`, dataUrl);
|
|
8063
|
+
}
|
|
8064
|
+
}
|
|
8065
|
+
return rewriteGedcomFilePaths(extracted.gedcomText, pathToDataUrl);
|
|
8066
|
+
};
|
|
8067
|
+
var extractGedzip = async (data) => {
|
|
8068
|
+
const zip = await JSZip.loadAsync(data);
|
|
8069
|
+
const entries = Object.values(zip.files).filter((entry) => !entry.dir);
|
|
8070
|
+
const preferred = entries.find(
|
|
8071
|
+
(entry) => normalizeZipPath(entry.name).toLowerCase() === GEDZIP_GEDCOM_ENTRY
|
|
8072
|
+
) ?? entries.find(
|
|
8073
|
+
(entry) => normalizeZipPath(entry.name).toLowerCase().endsWith(".ged")
|
|
8074
|
+
);
|
|
8075
|
+
if (!preferred) {
|
|
8076
|
+
throw new Error("No .ged file found in the archive.");
|
|
8077
|
+
}
|
|
8078
|
+
const gedcomText = await preferred.async("string");
|
|
8079
|
+
const mediaEntries = [];
|
|
8080
|
+
for (const entry of entries) {
|
|
8081
|
+
const path = normalizeZipPath(entry.name);
|
|
8082
|
+
if (path === normalizeZipPath(preferred.name)) {
|
|
8083
|
+
continue;
|
|
8084
|
+
}
|
|
8085
|
+
if (path.toLowerCase().endsWith(".ged")) {
|
|
8086
|
+
continue;
|
|
8087
|
+
}
|
|
8088
|
+
mediaEntries.push({
|
|
8089
|
+
path,
|
|
8090
|
+
content: await entry.async("uint8array")
|
|
8091
|
+
});
|
|
8092
|
+
}
|
|
8093
|
+
return {
|
|
8094
|
+
gedcomText,
|
|
8095
|
+
entryName: normalizeZipPath(preferred.name),
|
|
8096
|
+
mediaEntries
|
|
8097
|
+
};
|
|
8098
|
+
};
|
|
8099
|
+
var extractGedzipGedcom = async (data, options) => {
|
|
8100
|
+
const extracted = await extractGedzip(data);
|
|
8101
|
+
if (options?.embedMediaAsDataUrls === false) {
|
|
8102
|
+
return extracted.gedcomText;
|
|
8103
|
+
}
|
|
8104
|
+
return remountGedzipMediaAsDataUrls(extracted);
|
|
8105
|
+
};
|
|
8106
|
+
var isGedzipContainer = (file) => {
|
|
8107
|
+
const name = (file.name || "").toLowerCase();
|
|
8108
|
+
const type = (file.type || "").toLowerCase();
|
|
8109
|
+
return name.endsWith(`.${GEDZIP_EXTENSION}`) || name.endsWith(".zip") || type === GEDZIP_MIME || type === "application/zip" || type === "application/x-zip-compressed";
|
|
8110
|
+
};
|
|
8111
|
+
var downloadGedzipMedia = async (media, onProgress) => {
|
|
8112
|
+
const entries = Object.values(media).filter((item) => !!item.url);
|
|
8113
|
+
const total = entries.length;
|
|
8114
|
+
let done = 0;
|
|
8115
|
+
const downloaded = [];
|
|
8116
|
+
await Promise.all(
|
|
8117
|
+
entries.map(async (item) => {
|
|
8118
|
+
try {
|
|
8119
|
+
const resolved = await resolveMediaContent({
|
|
8120
|
+
url: item.url,
|
|
8121
|
+
id: item.id,
|
|
8122
|
+
imgId: item.imgId,
|
|
8123
|
+
key: "key" in item ? item.key : void 0,
|
|
8124
|
+
contentType: item.contentType
|
|
8125
|
+
});
|
|
8126
|
+
if (!resolved?.content) {
|
|
8127
|
+
return;
|
|
8128
|
+
}
|
|
8129
|
+
downloaded.push({
|
|
8130
|
+
...item,
|
|
8131
|
+
content: resolved.content,
|
|
8132
|
+
contentType: resolved.contentType || item.contentType
|
|
8133
|
+
});
|
|
8134
|
+
} catch {
|
|
8135
|
+
} finally {
|
|
8136
|
+
done += 1;
|
|
8137
|
+
onProgress?.(done, total);
|
|
8138
|
+
}
|
|
8139
|
+
})
|
|
8140
|
+
);
|
|
8141
|
+
return downloaded;
|
|
8142
|
+
};
|
|
8143
|
+
var buildGedzipBlob = async (gedcomText, mediaFiles = []) => {
|
|
8144
|
+
const bytes = await buildGedzip(gedcomText, mediaFiles);
|
|
8145
|
+
return new Blob([bytes], { type: GEDZIP_MIME });
|
|
7650
8146
|
};
|
|
7651
|
-
var getVersion = () => package_default.version;
|
|
7652
|
-
var getName = () => package_default.name;
|
|
7653
8147
|
|
|
7654
|
-
// src/
|
|
7655
|
-
var
|
|
7656
|
-
|
|
8148
|
+
// src/utils/gedcom7-enumerations.ts
|
|
8149
|
+
var GEDCOM7_SEX_VALUES = ["M", "F", "U", "X", "N"];
|
|
8150
|
+
var GEDCOM7_PEDI_VALUES = [
|
|
8151
|
+
"adopted",
|
|
8152
|
+
"birth",
|
|
8153
|
+
"foster",
|
|
8154
|
+
"sealing"
|
|
8155
|
+
];
|
|
8156
|
+
var GEDCOM7_ROLE_VALUES = [
|
|
8157
|
+
"CHIL",
|
|
8158
|
+
"CLERGY",
|
|
8159
|
+
"FATH",
|
|
8160
|
+
"FRIEND",
|
|
8161
|
+
"GODP",
|
|
8162
|
+
"HUSB",
|
|
8163
|
+
"MOTH",
|
|
8164
|
+
"MULTIPLE",
|
|
8165
|
+
"NGHBR",
|
|
8166
|
+
"OFFICIATOR",
|
|
8167
|
+
"OTHER",
|
|
8168
|
+
"PARENT",
|
|
8169
|
+
"SPOU",
|
|
8170
|
+
"WIFE",
|
|
8171
|
+
"WITN"
|
|
8172
|
+
];
|
|
8173
|
+
var GEDCOM7_RESN_VALUES = [
|
|
8174
|
+
"CONFIDENTIAL",
|
|
8175
|
+
"LOCKED",
|
|
8176
|
+
"PRIVACY"
|
|
8177
|
+
];
|
|
8178
|
+
var isAllowed = (value, allowed) => allowed.includes(value);
|
|
8179
|
+
var moveToPhrase = (node, phrase) => {
|
|
8180
|
+
const previousValue = node.value;
|
|
8181
|
+
const previousPhrase = node.get("PHRASE");
|
|
8182
|
+
const previousPhraseValue = previousPhrase?.toValue();
|
|
8183
|
+
node.removeValue();
|
|
8184
|
+
if (previousPhrase) {
|
|
8185
|
+
previousPhrase.value = phrase;
|
|
8186
|
+
} else {
|
|
8187
|
+
const phraseNode = createCommon(node.getGedcom(), void 0, node.main);
|
|
8188
|
+
phraseNode.value = phrase;
|
|
8189
|
+
node.set("PHRASE", phraseNode);
|
|
8190
|
+
}
|
|
8191
|
+
return () => {
|
|
8192
|
+
if (previousValue === void 0) {
|
|
8193
|
+
node.removeValue();
|
|
8194
|
+
} else {
|
|
8195
|
+
node.value = previousValue;
|
|
8196
|
+
}
|
|
8197
|
+
if (previousPhrase) {
|
|
8198
|
+
previousPhrase.value = previousPhraseValue;
|
|
8199
|
+
} else {
|
|
8200
|
+
node.remove("PHRASE");
|
|
8201
|
+
}
|
|
8202
|
+
};
|
|
7657
8203
|
};
|
|
7658
|
-
var
|
|
7659
|
-
|
|
7660
|
-
|
|
7661
|
-
|
|
7662
|
-
this.reflist = {};
|
|
7663
|
-
this.refcount = 0;
|
|
7664
|
-
delete this._gedcom;
|
|
7665
|
-
delete this.id;
|
|
7666
|
-
this.removeValue();
|
|
8204
|
+
var normalizeEnum = (node, allowed, mode, restores) => {
|
|
8205
|
+
const value = node?.toValue();
|
|
8206
|
+
if (!node || typeof value !== "string" || !value.trim()) {
|
|
8207
|
+
return;
|
|
7667
8208
|
}
|
|
7668
|
-
|
|
7669
|
-
|
|
7670
|
-
if (
|
|
7671
|
-
|
|
8209
|
+
const normalized = mode === "upper" ? value.trim().toUpperCase() : value.trim().toLowerCase();
|
|
8210
|
+
if (isAllowed(normalized, allowed)) {
|
|
8211
|
+
if (value !== normalized) {
|
|
8212
|
+
const previous = node.value;
|
|
8213
|
+
node.value = normalized;
|
|
8214
|
+
restores.push(() => {
|
|
8215
|
+
node.value = previous;
|
|
8216
|
+
});
|
|
7672
8217
|
}
|
|
7673
|
-
|
|
7674
|
-
|
|
8218
|
+
return;
|
|
8219
|
+
}
|
|
8220
|
+
restores.push(moveToPhrase(node, value.trim()));
|
|
8221
|
+
};
|
|
8222
|
+
var applyGedcom7Enumerations = (gedcom) => {
|
|
8223
|
+
const restores = [];
|
|
8224
|
+
gedcom.indis()?.forEach((indi) => {
|
|
8225
|
+
if (!indi) return;
|
|
8226
|
+
normalizeEnum(indi.get("SEX"), GEDCOM7_SEX_VALUES, "upper", restores);
|
|
8227
|
+
normalizeEnum(indi.get("RESN"), GEDCOM7_RESN_VALUES, "upper", restores);
|
|
8228
|
+
indi.get("FAMC")?.toList()?.forEach((famc) => {
|
|
8229
|
+
normalizeEnum(
|
|
8230
|
+
famc?.get("PEDI") ?? famc?.get("PEDT"),
|
|
8231
|
+
GEDCOM7_PEDI_VALUES,
|
|
8232
|
+
"lower",
|
|
8233
|
+
restores
|
|
8234
|
+
);
|
|
8235
|
+
});
|
|
8236
|
+
indi.get("ASSO")?.toList()?.forEach((asso) => {
|
|
8237
|
+
normalizeEnum(
|
|
8238
|
+
asso?.get("ROLE"),
|
|
8239
|
+
GEDCOM7_ROLE_VALUES,
|
|
8240
|
+
"upper",
|
|
8241
|
+
restores
|
|
8242
|
+
);
|
|
8243
|
+
});
|
|
8244
|
+
});
|
|
8245
|
+
gedcom.fams()?.forEach((fam) => {
|
|
8246
|
+
if (!fam) return;
|
|
8247
|
+
normalizeEnum(fam.get("RESN"), GEDCOM7_RESN_VALUES, "upper", restores);
|
|
8248
|
+
fam.get("ASSO")?.toList()?.forEach((asso) => {
|
|
8249
|
+
normalizeEnum(
|
|
8250
|
+
asso?.get("ROLE"),
|
|
8251
|
+
GEDCOM7_ROLE_VALUES,
|
|
8252
|
+
"upper",
|
|
8253
|
+
restores
|
|
8254
|
+
);
|
|
8255
|
+
});
|
|
8256
|
+
});
|
|
8257
|
+
return () => {
|
|
8258
|
+
for (let i = restores.length - 1; i >= 0; i -= 1) {
|
|
8259
|
+
restores[i]?.();
|
|
7675
8260
|
}
|
|
7676
|
-
|
|
7677
|
-
|
|
8261
|
+
};
|
|
8262
|
+
};
|
|
8263
|
+
|
|
8264
|
+
// src/utils/gedcom7-dates.ts
|
|
8265
|
+
var GEDCOM7_CALENDARS = [
|
|
8266
|
+
"GREGORIAN",
|
|
8267
|
+
"JULIAN",
|
|
8268
|
+
"FRENCH_R",
|
|
8269
|
+
"HEBREW"
|
|
8270
|
+
];
|
|
8271
|
+
var CALENDAR_PREFIX2 = /^(?<calendar>GREGORIAN|JULIAN|FRENCH_R|HEBREW)\b\s+/i;
|
|
8272
|
+
var parseGedcom7CalendarPrefix = (value) => {
|
|
8273
|
+
const match = value.match(CALENDAR_PREFIX2);
|
|
8274
|
+
if (!match?.groups?.calendar) {
|
|
8275
|
+
return { calendar: void 0, rest: value };
|
|
7678
8276
|
}
|
|
7679
|
-
|
|
7680
|
-
|
|
8277
|
+
return {
|
|
8278
|
+
calendar: match.groups.calendar.toUpperCase(),
|
|
8279
|
+
rest: value.slice(match[0].length)
|
|
8280
|
+
};
|
|
8281
|
+
};
|
|
8282
|
+
var withGedcom7Calendar = (value, calendar) => {
|
|
8283
|
+
if (!calendar || calendar.toUpperCase() === "GREGORIAN") {
|
|
8284
|
+
return value;
|
|
7681
8285
|
}
|
|
7682
|
-
|
|
7683
|
-
|
|
7684
|
-
|
|
8286
|
+
const upper = calendar.toUpperCase();
|
|
8287
|
+
if (GEDCOM7_CALENDARS.includes(upper)) {
|
|
8288
|
+
const { rest } = parseGedcom7CalendarPrefix(value);
|
|
8289
|
+
return `${upper} ${rest}`.trim();
|
|
8290
|
+
}
|
|
8291
|
+
return value;
|
|
8292
|
+
};
|
|
8293
|
+
var applyGedcom7DatePhrases = (gedcom) => {
|
|
8294
|
+
const restores = [];
|
|
8295
|
+
const visitDate = (dateNode) => {
|
|
8296
|
+
if (!dateNode || typeof dateNode.toValue !== "function") {
|
|
8297
|
+
return;
|
|
7685
8298
|
}
|
|
7686
|
-
const
|
|
7687
|
-
|
|
7688
|
-
|
|
7689
|
-
|
|
7690
|
-
|
|
7691
|
-
|
|
8299
|
+
const asDate = dateNode;
|
|
8300
|
+
const hasComponents = !!(asDate.DAY || asDate.MONTH || asDate.YEAR);
|
|
8301
|
+
const raw = dateNode.exportValue?.() ?? dateNode.toValue();
|
|
8302
|
+
if (typeof raw !== "string" || !raw.trim()) {
|
|
8303
|
+
return;
|
|
8304
|
+
}
|
|
8305
|
+
const { calendar, rest } = parseGedcom7CalendarPrefix(raw.trim());
|
|
8306
|
+
const looksStructured = hasComponents || /^(ABT|CAL|EST|BEF|AFT|FROM|TO|BET|INT)(\s|$)/i.test(rest) || /\bAND\b/i.test(rest) || /^\d{1,2}\s+[A-Z]{3}\s+\d{1,4}/i.test(rest) || /^[A-Z]{3}\s+\d{1,4}/i.test(rest) || /^\d{1,4}$/.test(rest);
|
|
8307
|
+
if (looksStructured) {
|
|
8308
|
+
if (calendar && calendar !== "GREGORIAN") {
|
|
8309
|
+
const previous = dateNode.value;
|
|
8310
|
+
const next = withGedcom7Calendar(rest, calendar);
|
|
8311
|
+
if (previous !== next) {
|
|
8312
|
+
dateNode.value = next;
|
|
8313
|
+
restores.push(() => {
|
|
8314
|
+
dateNode.value = previous;
|
|
8315
|
+
});
|
|
7692
8316
|
}
|
|
7693
|
-
}
|
|
7694
|
-
return
|
|
8317
|
+
}
|
|
8318
|
+
return;
|
|
7695
8319
|
}
|
|
7696
|
-
|
|
7697
|
-
|
|
7698
|
-
|
|
8320
|
+
const previousValue = dateNode.value;
|
|
8321
|
+
const previousPhrase = dateNode.get("PHRASE");
|
|
8322
|
+
const previousPhraseValue = previousPhrase?.toValue();
|
|
8323
|
+
dateNode.removeValue();
|
|
8324
|
+
if (previousPhrase) {
|
|
8325
|
+
previousPhrase.value = raw.trim();
|
|
8326
|
+
} else {
|
|
8327
|
+
const phrase = createCommon(
|
|
8328
|
+
dateNode.getGedcom(),
|
|
8329
|
+
void 0,
|
|
8330
|
+
dateNode.main
|
|
8331
|
+
);
|
|
8332
|
+
phrase.value = raw.trim();
|
|
8333
|
+
dateNode.set("PHRASE", phrase);
|
|
7699
8334
|
}
|
|
7700
|
-
|
|
7701
|
-
|
|
7702
|
-
|
|
7703
|
-
|
|
7704
|
-
|
|
7705
|
-
|
|
8335
|
+
restores.push(() => {
|
|
8336
|
+
if (previousValue === void 0) {
|
|
8337
|
+
dateNode.removeValue();
|
|
8338
|
+
} else {
|
|
8339
|
+
dateNode.value = previousValue;
|
|
8340
|
+
}
|
|
8341
|
+
if (previousPhrase) {
|
|
8342
|
+
previousPhrase.value = previousPhraseValue;
|
|
8343
|
+
} else {
|
|
8344
|
+
dateNode.remove("PHRASE");
|
|
8345
|
+
}
|
|
8346
|
+
});
|
|
8347
|
+
};
|
|
8348
|
+
const walk = (node) => {
|
|
8349
|
+
if (!node) return;
|
|
8350
|
+
node.get("DATE")?.toList()?.forEach((item) => visitDate(item));
|
|
8351
|
+
node.get("SDATE")?.toList()?.forEach((item) => visitDate(item));
|
|
8352
|
+
};
|
|
8353
|
+
gedcom.indis()?.forEach((indi) => {
|
|
8354
|
+
if (!indi) return;
|
|
8355
|
+
walk(indi);
|
|
8356
|
+
[
|
|
8357
|
+
"BIRT",
|
|
8358
|
+
"DEAT",
|
|
8359
|
+
"CHR",
|
|
8360
|
+
"BAPM",
|
|
8361
|
+
"BURI",
|
|
8362
|
+
"CREM",
|
|
8363
|
+
"ADOP",
|
|
8364
|
+
"EVEN",
|
|
8365
|
+
"RESI",
|
|
8366
|
+
"OCCU",
|
|
8367
|
+
"MARR"
|
|
8368
|
+
].forEach((tag) => {
|
|
8369
|
+
indi.get(tag)?.toList()?.forEach((event) => walk(event));
|
|
8370
|
+
});
|
|
8371
|
+
});
|
|
8372
|
+
gedcom.fams()?.forEach((fam) => {
|
|
8373
|
+
if (!fam) return;
|
|
8374
|
+
["MARR", "DIV", "ENGA", "ANUL", "EVEN"].forEach((tag) => {
|
|
8375
|
+
fam.get(tag)?.toList()?.forEach((event) => walk(event));
|
|
8376
|
+
});
|
|
8377
|
+
});
|
|
8378
|
+
return () => {
|
|
8379
|
+
for (let i = restores.length - 1; i >= 0; i -= 1) {
|
|
8380
|
+
restores[i]?.();
|
|
8381
|
+
}
|
|
8382
|
+
};
|
|
8383
|
+
};
|
|
8384
|
+
|
|
8385
|
+
// src/utils/uid.ts
|
|
8386
|
+
var createGedcomUid = () => {
|
|
8387
|
+
const cryptoObj = typeof globalThis !== "undefined" ? globalThis.crypto : void 0;
|
|
8388
|
+
if (cryptoObj && typeof cryptoObj.randomUUID === "function") {
|
|
8389
|
+
return cryptoObj.randomUUID();
|
|
8390
|
+
}
|
|
8391
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (char) => {
|
|
8392
|
+
const rand = Math.random() * 16 | 0;
|
|
8393
|
+
const value = char === "x" ? rand : rand & 3 | 8;
|
|
8394
|
+
return value.toString(16);
|
|
8395
|
+
});
|
|
8396
|
+
};
|
|
8397
|
+
|
|
8398
|
+
// src/utils/gedcom7-metadata.ts
|
|
8399
|
+
var GEDCOM_MONTHS2 = [
|
|
8400
|
+
"JAN",
|
|
8401
|
+
"FEB",
|
|
8402
|
+
"MAR",
|
|
8403
|
+
"APR",
|
|
8404
|
+
"MAY",
|
|
8405
|
+
"JUN",
|
|
8406
|
+
"JUL",
|
|
8407
|
+
"AUG",
|
|
8408
|
+
"SEP",
|
|
8409
|
+
"OCT",
|
|
8410
|
+
"NOV",
|
|
8411
|
+
"DEC"
|
|
8412
|
+
];
|
|
8413
|
+
var formatGedcom7Timestamp = (date = /* @__PURE__ */ new Date()) => {
|
|
8414
|
+
const day = String(date.getUTCDate());
|
|
8415
|
+
const month = GEDCOM_MONTHS2[date.getUTCMonth()];
|
|
8416
|
+
const year = String(date.getUTCFullYear());
|
|
8417
|
+
const hh = String(date.getUTCHours()).padStart(2, "0");
|
|
8418
|
+
const mm = String(date.getUTCMinutes()).padStart(2, "0");
|
|
8419
|
+
const ss = String(date.getUTCSeconds()).padStart(2, "0");
|
|
8420
|
+
return {
|
|
8421
|
+
date: `${day} ${month} ${year}`,
|
|
8422
|
+
time: `${hh}:${mm}:${ss}Z`
|
|
8423
|
+
};
|
|
8424
|
+
};
|
|
8425
|
+
var ensureMetaDate = (gedcom, record, tag, when, restores) => {
|
|
8426
|
+
if (record.get(tag)) {
|
|
8427
|
+
return;
|
|
8428
|
+
}
|
|
8429
|
+
const { date, time } = formatGedcom7Timestamp(when);
|
|
8430
|
+
const meta = createCommon(gedcom, void 0, record);
|
|
8431
|
+
meta.type = tag;
|
|
8432
|
+
const dateNode = createCommonDate(gedcom, void 0, record, meta);
|
|
8433
|
+
dateNode.type = "DATE";
|
|
8434
|
+
dateNode.value = date;
|
|
8435
|
+
dateNode.set("TIME", time);
|
|
8436
|
+
meta.set("DATE", dateNode);
|
|
8437
|
+
record.set(tag, meta);
|
|
8438
|
+
restores.push(() => {
|
|
8439
|
+
record.remove(tag);
|
|
8440
|
+
});
|
|
8441
|
+
};
|
|
8442
|
+
var ensureUid = (record, restores) => {
|
|
8443
|
+
const existing = record.get("UID")?.toValue();
|
|
8444
|
+
if (typeof existing === "string" && existing.trim()) {
|
|
8445
|
+
return;
|
|
8446
|
+
}
|
|
8447
|
+
const uid = createGedcomUid();
|
|
8448
|
+
record.set("UID", uid);
|
|
8449
|
+
restores.push(() => {
|
|
8450
|
+
record.remove("UID");
|
|
8451
|
+
});
|
|
8452
|
+
};
|
|
8453
|
+
var applyGedcom7RecordMetadata = (gedcom, options) => {
|
|
8454
|
+
const restores = [];
|
|
8455
|
+
const now = options?.now ?? /* @__PURE__ */ new Date();
|
|
8456
|
+
const visit = (record) => {
|
|
8457
|
+
if (!record?.id) {
|
|
8458
|
+
return;
|
|
8459
|
+
}
|
|
8460
|
+
ensureUid(record, restores);
|
|
8461
|
+
ensureMetaDate(gedcom, record, "CREA", now, restores);
|
|
8462
|
+
ensureMetaDate(gedcom, record, "CHAN", now, restores);
|
|
8463
|
+
};
|
|
8464
|
+
gedcom.indis()?.forEach((indi) => visit(indi));
|
|
8465
|
+
gedcom.fams()?.forEach((fam) => visit(fam));
|
|
8466
|
+
gedcom.objes()?.forEach((obje) => visit(obje));
|
|
8467
|
+
gedcom.sours()?.forEach((sour) => visit(sour));
|
|
8468
|
+
gedcom.repos()?.forEach((repo) => visit(repo));
|
|
8469
|
+
gedcom.subms()?.forEach((subm) => visit(subm));
|
|
8470
|
+
gedcom.snotes()?.forEach((note) => visit(note));
|
|
8471
|
+
return () => {
|
|
8472
|
+
for (let i = restores.length - 1; i >= 0; i -= 1) {
|
|
8473
|
+
restores[i]?.();
|
|
8474
|
+
}
|
|
8475
|
+
};
|
|
8476
|
+
};
|
|
8477
|
+
|
|
8478
|
+
// src/utils/gedcom7-schema.ts
|
|
8479
|
+
var TREEVIZ_EXTENSION_BASE_URI = "https://treeviz.com/gedcom";
|
|
8480
|
+
var TREEVIZ_EXTENSION_URIS = {
|
|
8481
|
+
_ORIGHEAD: `${TREEVIZ_EXTENSION_BASE_URI}#_ORIGHEAD`,
|
|
8482
|
+
_TREE: `${TREEVIZ_EXTENSION_BASE_URI}#_TREE`,
|
|
8483
|
+
_TID: `${TREEVIZ_EXTENSION_BASE_URI}#_TID`,
|
|
8484
|
+
_PRIM: `${TREEVIZ_EXTENSION_BASE_URI}#_PRIM`,
|
|
8485
|
+
_FREL: `${TREEVIZ_EXTENSION_BASE_URI}#_FREL`,
|
|
8486
|
+
_MREL: `${TREEVIZ_EXTENSION_BASE_URI}#_MREL`,
|
|
8487
|
+
_SREL: `${TREEVIZ_EXTENSION_BASE_URI}#_SREL`,
|
|
8488
|
+
_UID: `${TREEVIZ_EXTENSION_BASE_URI}#_UID`,
|
|
8489
|
+
_WLNK: `${TREEVIZ_EXTENSION_BASE_URI}#_WLNK`,
|
|
8490
|
+
_MTTAG: `${TREEVIZ_EXTENSION_BASE_URI}#_MTTAG`,
|
|
8491
|
+
_MTCAT: `${TREEVIZ_EXTENSION_BASE_URI}#_MTCAT`,
|
|
8492
|
+
_CLON: `${TREEVIZ_EXTENSION_BASE_URI}#_CLON`,
|
|
8493
|
+
_MSER: `${TREEVIZ_EXTENSION_BASE_URI}#_MSER`,
|
|
8494
|
+
_OID: `${TREEVIZ_EXTENSION_BASE_URI}#_OID`,
|
|
8495
|
+
_LKID: `${TREEVIZ_EXTENSION_BASE_URI}#_LKID`,
|
|
8496
|
+
_PHOTO_RIN: `${TREEVIZ_EXTENSION_BASE_URI}#_PHOTO_RIN`,
|
|
8497
|
+
_EXPORTED_FROM_SITE_ID: `${TREEVIZ_EXTENSION_BASE_URI}#_EXPORTED_FROM_SITE_ID`,
|
|
8498
|
+
_FS_ID: `${TREEVIZ_EXTENSION_BASE_URI}#_FS_ID`,
|
|
8499
|
+
_FS_LINK: `${TREEVIZ_EXTENSION_BASE_URI}#_FS_LINK`,
|
|
8500
|
+
_FS_MATCH: `${TREEVIZ_EXTENSION_BASE_URI}#_FS_MATCH`,
|
|
8501
|
+
_FS_SOUR: `${TREEVIZ_EXTENSION_BASE_URI}#_FS_SOUR`,
|
|
8502
|
+
_IS_FS: `${TREEVIZ_EXTENSION_BASE_URI}#_IS_FS`,
|
|
8503
|
+
_LABEL: `${TREEVIZ_EXTENSION_BASE_URI}#_LABEL`,
|
|
8504
|
+
_MILT: `${TREEVIZ_EXTENSION_BASE_URI}#_MILT`,
|
|
8505
|
+
_MILTID: `${TREEVIZ_EXTENSION_BASE_URI}#_MILTID`,
|
|
8506
|
+
_ORIG: `${TREEVIZ_EXTENSION_BASE_URI}#_ORIG`,
|
|
8507
|
+
_ENV: `${TREEVIZ_EXTENSION_BASE_URI}#_ENV`,
|
|
8508
|
+
_TREEVIZ_SETTINGS: `${TREEVIZ_EXTENSION_BASE_URI}#_TREEVIZ_SETTINGS`,
|
|
8509
|
+
_TREEVIZ_VIEW: `${TREEVIZ_EXTENSION_BASE_URI}#_TREEVIZ_VIEW`,
|
|
8510
|
+
_TREEVIZ_DETECTIVE: `${TREEVIZ_EXTENSION_BASE_URI}#_TREEVIZ_DETECTIVE`,
|
|
8511
|
+
_TREEVIZ_DETECTIVE_STATE: `${TREEVIZ_EXTENSION_BASE_URI}#_TREEVIZ_DETECTIVE_STATE`
|
|
8512
|
+
};
|
|
8513
|
+
var parseTagDefinition = (payload) => {
|
|
8514
|
+
const trimmed = payload.trim();
|
|
8515
|
+
const space = trimmed.indexOf(" ");
|
|
8516
|
+
if (space <= 0) {
|
|
8517
|
+
return void 0;
|
|
8518
|
+
}
|
|
8519
|
+
const tag = trimmed.slice(0, space).trim();
|
|
8520
|
+
const uri = trimmed.slice(space + 1).trim();
|
|
8521
|
+
if (!tag || !uri) {
|
|
8522
|
+
return void 0;
|
|
8523
|
+
}
|
|
8524
|
+
return { tag, uri };
|
|
8525
|
+
};
|
|
8526
|
+
var getExtensionSchema = (gedcom) => {
|
|
8527
|
+
const map = /* @__PURE__ */ new Map();
|
|
8528
|
+
const schma = gedcom.get("HEAD")?.get("SCHMA");
|
|
8529
|
+
if (!schma) {
|
|
8530
|
+
return map;
|
|
8531
|
+
}
|
|
8532
|
+
schma.get("TAG")?.toList()?.forEach((tagNode) => {
|
|
8533
|
+
const payload = tagNode?.toValue();
|
|
8534
|
+
if (typeof payload !== "string") {
|
|
8535
|
+
return;
|
|
8536
|
+
}
|
|
8537
|
+
const parsed = parseTagDefinition(payload);
|
|
8538
|
+
if (parsed) {
|
|
8539
|
+
map.set(parsed.tag.toUpperCase(), parsed.uri);
|
|
8540
|
+
}
|
|
8541
|
+
});
|
|
8542
|
+
return map;
|
|
8543
|
+
};
|
|
8544
|
+
var ensureSchemaNode = (gedcom) => {
|
|
8545
|
+
const head = gedcom.get("HEAD");
|
|
8546
|
+
if (!head) {
|
|
8547
|
+
return void 0;
|
|
8548
|
+
}
|
|
8549
|
+
let schma = head.get("SCHMA");
|
|
8550
|
+
if (!schma) {
|
|
8551
|
+
schma = createCommon(gedcom, void 0, head);
|
|
8552
|
+
head.set("SCHMA", schma);
|
|
8553
|
+
}
|
|
8554
|
+
return schma;
|
|
8555
|
+
};
|
|
8556
|
+
var registerExtensionTag = (gedcom, tag, uri) => {
|
|
8557
|
+
const normalizedTag = tag.trim().toUpperCase();
|
|
8558
|
+
const normalizedUri = uri.trim();
|
|
8559
|
+
if (!normalizedTag.startsWith("_") || !normalizedUri) {
|
|
8560
|
+
return void 0;
|
|
8561
|
+
}
|
|
8562
|
+
const schma = ensureSchemaNode(gedcom);
|
|
8563
|
+
if (!schma) {
|
|
8564
|
+
return void 0;
|
|
8565
|
+
}
|
|
8566
|
+
const payload = `${normalizedTag} ${normalizedUri}`;
|
|
8567
|
+
const existingList = schma.get("TAG")?.toList();
|
|
8568
|
+
const existing = existingList?.values().find((node) => {
|
|
8569
|
+
const value = node?.toValue();
|
|
8570
|
+
return typeof value === "string" && value.trim().toUpperCase().startsWith(`${normalizedTag} `);
|
|
8571
|
+
});
|
|
8572
|
+
if (existing) {
|
|
8573
|
+
existing.value = payload;
|
|
8574
|
+
return existing;
|
|
8575
|
+
}
|
|
8576
|
+
const tagNode = createCommon(gedcom, void 0, schma);
|
|
8577
|
+
tagNode.value = payload;
|
|
8578
|
+
schma.assign("TAG", tagNode);
|
|
8579
|
+
return tagNode;
|
|
8580
|
+
};
|
|
8581
|
+
var ensureExtensionSchema = (gedcom, extraTags) => {
|
|
8582
|
+
const head = gedcom.get("HEAD");
|
|
8583
|
+
const hadSchma = !!head?.get("SCHMA");
|
|
8584
|
+
const previousPayloads = head?.get("SCHMA")?.get("TAG")?.toList()?.values().map((node) => ({
|
|
8585
|
+
node,
|
|
8586
|
+
value: node?.toValue()
|
|
8587
|
+
})) ?? [];
|
|
8588
|
+
const tags = /* @__PURE__ */ new Set([
|
|
8589
|
+
...Object.keys(TREEVIZ_EXTENSION_URIS),
|
|
8590
|
+
...(extraTags ?? []).map((tag) => tag.toUpperCase())
|
|
8591
|
+
]);
|
|
8592
|
+
tags.forEach((tag) => {
|
|
8593
|
+
const uri = TREEVIZ_EXTENSION_URIS[tag] ?? `${TREEVIZ_EXTENSION_BASE_URI}#${tag}`;
|
|
8594
|
+
if (tag.startsWith("_")) {
|
|
8595
|
+
registerExtensionTag(gedcom, tag, uri);
|
|
8596
|
+
}
|
|
8597
|
+
});
|
|
8598
|
+
return () => {
|
|
8599
|
+
if (!head) {
|
|
8600
|
+
return;
|
|
8601
|
+
}
|
|
8602
|
+
if (!hadSchma) {
|
|
8603
|
+
head.remove("SCHMA");
|
|
8604
|
+
return;
|
|
8605
|
+
}
|
|
8606
|
+
const schma = head.get("SCHMA");
|
|
8607
|
+
const list = schma?.get("TAG")?.toList();
|
|
8608
|
+
const keep = new Set(
|
|
8609
|
+
previousPayloads.map(
|
|
8610
|
+
(item) => typeof item.value === "string" ? item.value : void 0
|
|
8611
|
+
).filter((value) => !!value)
|
|
8612
|
+
);
|
|
8613
|
+
list?.values().forEach((node) => {
|
|
8614
|
+
const value = node?.toValue();
|
|
8615
|
+
if (typeof value === "string" && !keep.has(value) && node) {
|
|
8616
|
+
list.delete(node);
|
|
8617
|
+
}
|
|
8618
|
+
});
|
|
8619
|
+
previousPayloads.forEach(({ node, value }) => {
|
|
8620
|
+
if (node && value !== void 0) {
|
|
8621
|
+
node.value = value;
|
|
8622
|
+
}
|
|
8623
|
+
});
|
|
8624
|
+
};
|
|
8625
|
+
};
|
|
8626
|
+
var collectExtensionTagsFrom = (node, into = /* @__PURE__ */ new Set()) => {
|
|
8627
|
+
if (!node) {
|
|
8628
|
+
return into;
|
|
8629
|
+
}
|
|
8630
|
+
const keys = Object.keys(node).filter(
|
|
8631
|
+
(key) => key.startsWith("_") && !key.startsWith("_gedcom") && !key.startsWith("_value") && !key.startsWith("_id") && !key.startsWith("_main") && !key.startsWith("_parent") && !key.startsWith("_unique") && !key.startsWith("_type") && !key.startsWith("_refs") && !key.startsWith("_date")
|
|
8632
|
+
);
|
|
8633
|
+
keys.forEach((key) => {
|
|
8634
|
+
const tag = key.toUpperCase();
|
|
8635
|
+
if (/^_[A-Z0-9_]+$/.test(tag)) {
|
|
8636
|
+
into.add(tag);
|
|
8637
|
+
}
|
|
8638
|
+
});
|
|
8639
|
+
return into;
|
|
8640
|
+
};
|
|
8641
|
+
|
|
8642
|
+
// package.json
|
|
8643
|
+
var package_default = {
|
|
8644
|
+
name: "@treeviz/gedcom-parser",
|
|
8645
|
+
version: "2.1.1"};
|
|
8646
|
+
|
|
8647
|
+
// src/utils/get-product-details.ts
|
|
8648
|
+
var isDevelopment = () => {
|
|
8649
|
+
return !process.env.NODE_ENV || process.env.NODE_ENV === "development";
|
|
8650
|
+
};
|
|
8651
|
+
var getVersion = () => package_default.version;
|
|
8652
|
+
var getName = () => package_default.name;
|
|
8653
|
+
|
|
8654
|
+
// src/utils/multimedia.ts
|
|
8655
|
+
var inferMediaForm = (file, fallback = "bin") => {
|
|
8656
|
+
const withoutQuery = file.split("?")[0] || file;
|
|
8657
|
+
const ext = getFileExtension(withoutQuery);
|
|
8658
|
+
if (ext) {
|
|
8659
|
+
return ext.toLowerCase() === "jpeg" ? "jpg" : ext.toLowerCase();
|
|
8660
|
+
}
|
|
8661
|
+
return fallback;
|
|
8662
|
+
};
|
|
8663
|
+
var mergeMediaLists = (...lists) => {
|
|
8664
|
+
const merged = {};
|
|
8665
|
+
for (const list of lists) {
|
|
8666
|
+
if (!list) continue;
|
|
8667
|
+
Object.assign(merged, list);
|
|
8668
|
+
}
|
|
8669
|
+
return merged;
|
|
8670
|
+
};
|
|
8671
|
+
var isObjePointer = (value) => typeof value === "string" && /^@O\d+@$/.test(value);
|
|
8672
|
+
|
|
8673
|
+
// src/classes/note.ts
|
|
8674
|
+
var CommonNote = class extends Common {
|
|
8675
|
+
constructor(gedcom, id, main, parent) {
|
|
8676
|
+
super(gedcom, id, main, parent);
|
|
8677
|
+
if (!id) {
|
|
8678
|
+
delete this.id;
|
|
8679
|
+
}
|
|
8680
|
+
}
|
|
8681
|
+
set value(value) {
|
|
8682
|
+
const [note, ...contents] = value?.split(/\r?\n/) ?? [];
|
|
8683
|
+
this._value = note;
|
|
8684
|
+
if (contents.length) {
|
|
8685
|
+
const newContents = new List();
|
|
8686
|
+
contents.forEach((c, i) => {
|
|
8687
|
+
const newContent = createCommon(
|
|
8688
|
+
this._gedcom,
|
|
8689
|
+
void 0,
|
|
8690
|
+
this.main
|
|
8691
|
+
);
|
|
8692
|
+
newContent.id = `@U${i}@`;
|
|
8693
|
+
newContent.value = c;
|
|
8694
|
+
newContents.append(newContent);
|
|
8695
|
+
});
|
|
8696
|
+
const firstItem = newContents.index(0);
|
|
8697
|
+
if (firstItem) {
|
|
8698
|
+
if (newContents.length === 1) {
|
|
8699
|
+
this.set("CONT", firstItem);
|
|
8700
|
+
} else {
|
|
8701
|
+
this.set("CONT", newContents);
|
|
8702
|
+
}
|
|
8703
|
+
}
|
|
8704
|
+
}
|
|
8705
|
+
}
|
|
8706
|
+
get value() {
|
|
8707
|
+
const contents = this.get("CONT")?.toList().map((content) => content.value).join("\n");
|
|
8708
|
+
if (contents) {
|
|
8709
|
+
return `${this._value}
|
|
8710
|
+
${contents}`;
|
|
8711
|
+
}
|
|
8712
|
+
return this._value;
|
|
8713
|
+
}
|
|
8714
|
+
exportValue() {
|
|
8715
|
+
return this._value;
|
|
8716
|
+
}
|
|
8717
|
+
};
|
|
8718
|
+
var createCommonNote = (gedcom, id, main, parent) => {
|
|
8719
|
+
return createProxy(
|
|
8720
|
+
new CommonNote(gedcom, id, main, parent)
|
|
8721
|
+
);
|
|
8722
|
+
};
|
|
8723
|
+
|
|
8724
|
+
// src/classes/obje.ts
|
|
8725
|
+
var Obje = class extends Common {
|
|
8726
|
+
standardizeMedia(namespace, override = true, urlGetter, gedcomVersion) {
|
|
8727
|
+
if (!this._gedcom) {
|
|
8728
|
+
return this;
|
|
8729
|
+
}
|
|
8730
|
+
const rin = this?.get("RIN")?.toValue();
|
|
8731
|
+
const clone = this?.get("_CLON._OID")?.toValue();
|
|
8732
|
+
const mser = this?.get("_MSER._LKID")?.toValue();
|
|
8733
|
+
const title = this?.get("FILE.TITL")?.toValue() ?? this?.get("TITL")?.toValue() ?? "";
|
|
8734
|
+
const note = this?.get("FILE.NOTE")?.toValue() ?? this?.get("NOTE")?.toValue() ?? "";
|
|
8735
|
+
const formRaw = this?.get("FILE.FORM")?.toValue() ?? this?.get("FORM")?.toValue();
|
|
8736
|
+
const mediType = this?.get("FILE.FORM.TYPE")?.toValue() ?? this?.get("FORM.TYPE")?.toValue() ?? this?.get("MEDI")?.toValue();
|
|
8737
|
+
const file = this?.get("FILE")?.toValue();
|
|
8738
|
+
const imgId = rin || clone || mser;
|
|
8739
|
+
const url = file || namespace && urlGetter?.(namespace, imgId);
|
|
8740
|
+
if (!url) {
|
|
8741
|
+
return this;
|
|
8742
|
+
}
|
|
8743
|
+
const version = normalizeGedcomVersion(
|
|
8744
|
+
gedcomVersion ?? this._gedcom.getGedcomVersion?.()
|
|
8745
|
+
);
|
|
8746
|
+
const form = formRaw || inferMediaForm(String(url));
|
|
8747
|
+
const newObject = createObje(this._gedcom, this.id, this.main);
|
|
8748
|
+
if (!override) {
|
|
8749
|
+
Object.assign(newObject, this);
|
|
8750
|
+
}
|
|
8751
|
+
const fileNode = createCommon(this._gedcom, void 0, this.main);
|
|
8752
|
+
fileNode.value = url;
|
|
8753
|
+
if (version === "7.0") {
|
|
8754
|
+
const formNode = createCommon(this._gedcom, void 0, fileNode);
|
|
8755
|
+
formNode.value = form;
|
|
8756
|
+
if (mediType) {
|
|
8757
|
+
formNode.set("TYPE", String(mediType));
|
|
8758
|
+
}
|
|
8759
|
+
fileNode.set("FORM", formNode);
|
|
8760
|
+
if (title) {
|
|
8761
|
+
fileNode.set("TITL", String(title));
|
|
8762
|
+
}
|
|
8763
|
+
if (note) {
|
|
8764
|
+
fileNode.set("NOTE", String(note));
|
|
8765
|
+
}
|
|
8766
|
+
newObject.set("FILE", fileNode);
|
|
8767
|
+
} else {
|
|
8768
|
+
newObject.set("FILE", fileNode);
|
|
8769
|
+
newObject.set("FORM", form);
|
|
8770
|
+
if (mediType) {
|
|
8771
|
+
newObject.set("MEDI", String(mediType));
|
|
8772
|
+
}
|
|
8773
|
+
if (title) {
|
|
8774
|
+
newObject.set("TITL", String(title));
|
|
8775
|
+
if (!note) {
|
|
8776
|
+
newObject.set("NOTE", String(title));
|
|
8777
|
+
}
|
|
8778
|
+
}
|
|
8779
|
+
if (note) {
|
|
8780
|
+
newObject.set("NOTE", String(note));
|
|
8781
|
+
if (!title) {
|
|
8782
|
+
newObject.set("TITL", String(note));
|
|
8783
|
+
}
|
|
8784
|
+
}
|
|
8785
|
+
}
|
|
8786
|
+
const prim = this.get("_PRIM")?.toValue();
|
|
8787
|
+
if (prim === "Y" || prim === "N") {
|
|
8788
|
+
newObject.set("_PRIM", prim);
|
|
8789
|
+
}
|
|
8790
|
+
const photoRin = this.get("_PHOTO_RIN")?.toValue();
|
|
8791
|
+
if (rin) {
|
|
8792
|
+
newObject.set("RIN", String(rin));
|
|
8793
|
+
}
|
|
8794
|
+
if (photoRin) {
|
|
8795
|
+
newObject.set("_PHOTO_RIN", String(photoRin));
|
|
8796
|
+
}
|
|
8797
|
+
const clonNode = this.get("_CLON");
|
|
8798
|
+
if (clonNode) {
|
|
8799
|
+
newObject.set("_CLON", clonNode);
|
|
8800
|
+
}
|
|
8801
|
+
const mserNode = this.get("_MSER");
|
|
8802
|
+
if (mserNode) {
|
|
8803
|
+
newObject.set("_MSER", mserNode);
|
|
8804
|
+
}
|
|
8805
|
+
const oidNode = this.get("_OID");
|
|
8806
|
+
if (oidNode && !newObject.get("_OID")) {
|
|
8807
|
+
newObject.set("_OID", oidNode);
|
|
8808
|
+
}
|
|
8809
|
+
const lkidNode = this.get("_LKID");
|
|
8810
|
+
if (lkidNode && !newObject.get("_LKID")) {
|
|
8811
|
+
newObject.set("_LKID", lkidNode);
|
|
8812
|
+
}
|
|
8813
|
+
if (override) {
|
|
8814
|
+
this.remove("FILE");
|
|
8815
|
+
this.remove("FORM");
|
|
8816
|
+
this.remove("MEDI");
|
|
8817
|
+
this.remove("TITL");
|
|
8818
|
+
this.remove("NOTE");
|
|
8819
|
+
Object.assign(this, newObject);
|
|
8820
|
+
return this;
|
|
8821
|
+
}
|
|
8822
|
+
return newObject;
|
|
8823
|
+
}
|
|
8824
|
+
};
|
|
8825
|
+
var createObje = (gedcom, id, main, parent) => {
|
|
8826
|
+
return createProxy(
|
|
8827
|
+
new Obje(gedcom, id, main, parent)
|
|
8828
|
+
);
|
|
8829
|
+
};
|
|
8830
|
+
|
|
8831
|
+
// src/classes/objes.ts
|
|
8832
|
+
var Objects = class _Objects extends List {
|
|
8833
|
+
copy() {
|
|
8834
|
+
const newList = new _Objects();
|
|
8835
|
+
this.entries().forEach(([key, value]) => {
|
|
8836
|
+
newList.item(key, value);
|
|
8837
|
+
});
|
|
8838
|
+
return newList;
|
|
8839
|
+
}
|
|
8840
|
+
except(item) {
|
|
8841
|
+
return this.copy().delete(item);
|
|
8842
|
+
}
|
|
8843
|
+
};
|
|
8844
|
+
|
|
8845
|
+
// src/classes/gedcom.ts
|
|
8846
|
+
var isObjectPatch = (value) => {
|
|
8847
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
8848
|
+
};
|
|
8849
|
+
var GedCom = class extends Common {
|
|
8850
|
+
constructor() {
|
|
8851
|
+
super();
|
|
8852
|
+
this.tagMembers = {};
|
|
8853
|
+
this.reflist = {};
|
|
8854
|
+
this.refcount = 0;
|
|
8855
|
+
delete this._gedcom;
|
|
8856
|
+
delete this.id;
|
|
8857
|
+
this.removeValue();
|
|
8858
|
+
}
|
|
8859
|
+
getMain(type, index) {
|
|
8860
|
+
const list = !type || type instanceof List ? type : this.getList(type);
|
|
8861
|
+
if (!list) {
|
|
8862
|
+
return void 0;
|
|
8863
|
+
}
|
|
8864
|
+
if (typeof index === "string") {
|
|
8865
|
+
return list.item(index);
|
|
8866
|
+
}
|
|
8867
|
+
const keys = list.keys();
|
|
8868
|
+
return list.item(keys[index]);
|
|
8869
|
+
}
|
|
8870
|
+
getList(type) {
|
|
8871
|
+
return this.get(type);
|
|
8872
|
+
}
|
|
8873
|
+
createNodeFromPatchValue(value, main) {
|
|
8874
|
+
if (value === void 0 || value === null) {
|
|
8875
|
+
return void 0;
|
|
8876
|
+
}
|
|
8877
|
+
const node = createCommon(this, void 0, main);
|
|
8878
|
+
if (Array.isArray(value)) {
|
|
8879
|
+
value.forEach((item) => {
|
|
8880
|
+
const childNode = this.createNodeFromPatchValue(item, node);
|
|
8881
|
+
if (childNode) {
|
|
8882
|
+
node.assign("DATA", childNode);
|
|
8883
|
+
}
|
|
8884
|
+
});
|
|
8885
|
+
return node;
|
|
8886
|
+
}
|
|
8887
|
+
if (isObjectPatch(value)) {
|
|
8888
|
+
this.applyObjectToCommon(node, value);
|
|
8889
|
+
return node;
|
|
8890
|
+
}
|
|
8891
|
+
node.value = String(value);
|
|
8892
|
+
return node;
|
|
8893
|
+
}
|
|
8894
|
+
applyObjectToCommon(target, patch) {
|
|
8895
|
+
Object.entries(patch).forEach(([rawTag, value]) => {
|
|
8896
|
+
if (rawTag === "value") {
|
|
7706
8897
|
if (value === null || value === void 0 || Array.isArray(value) || isObjectPatch(value)) {
|
|
7707
8898
|
return;
|
|
7708
8899
|
}
|
|
@@ -7869,6 +9060,9 @@ var GedCom = class extends Common {
|
|
|
7869
9060
|
const id = this.nextIndiKey();
|
|
7870
9061
|
const indi = createIndi(this, id);
|
|
7871
9062
|
indi.type = "INDI";
|
|
9063
|
+
if (this.getGedcomVersion() === "7.0") {
|
|
9064
|
+
indi.set("UID", createGedcomUid());
|
|
9065
|
+
}
|
|
7872
9066
|
indis.item(id, indi);
|
|
7873
9067
|
return indi;
|
|
7874
9068
|
}
|
|
@@ -7881,9 +9075,151 @@ var GedCom = class extends Common {
|
|
|
7881
9075
|
const id = this.nextFamKey();
|
|
7882
9076
|
const fam = createFam(this, id);
|
|
7883
9077
|
fam.type = "FAM";
|
|
9078
|
+
if (this.getGedcomVersion() === "7.0") {
|
|
9079
|
+
fam.set("UID", createGedcomUid());
|
|
9080
|
+
}
|
|
7884
9081
|
fams.item(id, fam);
|
|
7885
9082
|
return fam;
|
|
7886
9083
|
}
|
|
9084
|
+
nextObjeKey() {
|
|
9085
|
+
const ids = [];
|
|
9086
|
+
this.objes()?.forEach((_obje, id) => {
|
|
9087
|
+
ids.push(String(id));
|
|
9088
|
+
});
|
|
9089
|
+
return nextRecordId(ids, "O");
|
|
9090
|
+
}
|
|
9091
|
+
/**
|
|
9092
|
+
* Create a top-level multimedia record (`0 @On@ OBJE`) with FILE/FORM/TITL.
|
|
9093
|
+
* GEDCOM 7 uses nested `FILE → FORM [→ TYPE]`; 5.5.1 uses sibling FORM/TITL.
|
|
9094
|
+
*/
|
|
9095
|
+
createMultimediaRecord(input) {
|
|
9096
|
+
const existing = this.objes();
|
|
9097
|
+
const objes = existing ?? new Objects();
|
|
9098
|
+
if (!existing) {
|
|
9099
|
+
this.set("@@OBJE", objes);
|
|
9100
|
+
}
|
|
9101
|
+
const id = this.nextObjeKey();
|
|
9102
|
+
const obje = createObje(this, id);
|
|
9103
|
+
obje.type = "OBJE";
|
|
9104
|
+
objes.item(id, obje);
|
|
9105
|
+
const version = normalizeGedcomVersion(
|
|
9106
|
+
input.gedcomVersion ?? this.getGedcomVersion()
|
|
9107
|
+
);
|
|
9108
|
+
const form = input.form || inferMediaForm(input.file);
|
|
9109
|
+
const fileNode = createCommon(this, void 0, obje);
|
|
9110
|
+
fileNode.value = input.file;
|
|
9111
|
+
if (version === "7.0") {
|
|
9112
|
+
const formNode = createCommon(
|
|
9113
|
+
this,
|
|
9114
|
+
void 0,
|
|
9115
|
+
fileNode
|
|
9116
|
+
);
|
|
9117
|
+
formNode.value = form;
|
|
9118
|
+
if (input.mediType) {
|
|
9119
|
+
formNode.set("TYPE", input.mediType);
|
|
9120
|
+
}
|
|
9121
|
+
fileNode.set("FORM", formNode);
|
|
9122
|
+
if (input.title) {
|
|
9123
|
+
fileNode.set("TITL", input.title);
|
|
9124
|
+
}
|
|
9125
|
+
obje.set("FILE", fileNode);
|
|
9126
|
+
} else {
|
|
9127
|
+
obje.set("FILE", fileNode);
|
|
9128
|
+
obje.set("FORM", form);
|
|
9129
|
+
if (input.mediType) {
|
|
9130
|
+
obje.set("MEDI", input.mediType);
|
|
9131
|
+
}
|
|
9132
|
+
if (input.title) {
|
|
9133
|
+
obje.set("TITL", input.title);
|
|
9134
|
+
}
|
|
9135
|
+
}
|
|
9136
|
+
if (input.primary) {
|
|
9137
|
+
obje.set("_PRIM", "Y");
|
|
9138
|
+
}
|
|
9139
|
+
if (normalizeGedcomVersion(
|
|
9140
|
+
input.gedcomVersion ?? this.getGedcomVersion()
|
|
9141
|
+
) === "7.0") {
|
|
9142
|
+
obje.set("UID", createGedcomUid());
|
|
9143
|
+
}
|
|
9144
|
+
return obje;
|
|
9145
|
+
}
|
|
9146
|
+
nextSnoteKey() {
|
|
9147
|
+
const ids = [];
|
|
9148
|
+
this.snotes()?.forEach((_note, id) => {
|
|
9149
|
+
ids.push(String(id));
|
|
9150
|
+
});
|
|
9151
|
+
return nextRecordId(ids, "N");
|
|
9152
|
+
}
|
|
9153
|
+
snotes() {
|
|
9154
|
+
return this.getList("@@SNOTE");
|
|
9155
|
+
}
|
|
9156
|
+
snote(index) {
|
|
9157
|
+
return this.getMain(this.snotes(), index);
|
|
9158
|
+
}
|
|
9159
|
+
/**
|
|
9160
|
+
* Create a top-level shared note record (`0 @Nn@ SNOTE` for GEDCOM 7).
|
|
9161
|
+
*/
|
|
9162
|
+
createSharedNote(text) {
|
|
9163
|
+
const existing = this.snotes();
|
|
9164
|
+
const notes = existing ?? new List();
|
|
9165
|
+
if (!existing) {
|
|
9166
|
+
this.set("@@SNOTE", notes);
|
|
9167
|
+
}
|
|
9168
|
+
const id = this.nextSnoteKey();
|
|
9169
|
+
const note = createCommonNote(this, id);
|
|
9170
|
+
note.type = "SNOTE";
|
|
9171
|
+
note.value = text;
|
|
9172
|
+
if (this.getGedcomVersion() === "7.0") {
|
|
9173
|
+
note.set("UID", createGedcomUid());
|
|
9174
|
+
}
|
|
9175
|
+
notes.item(id, note);
|
|
9176
|
+
return note;
|
|
9177
|
+
}
|
|
9178
|
+
registerExtensionTag(tag, uri) {
|
|
9179
|
+
return registerExtensionTag(this, tag, uri);
|
|
9180
|
+
}
|
|
9181
|
+
getExtensionSchema() {
|
|
9182
|
+
return getExtensionSchema(this);
|
|
9183
|
+
}
|
|
9184
|
+
ensureExtensionSchema(extraTags) {
|
|
9185
|
+
ensureExtensionSchema(this, extraTags);
|
|
9186
|
+
return getExtensionSchema(this);
|
|
9187
|
+
}
|
|
9188
|
+
/**
|
|
9189
|
+
* Collect multimedia descriptors via each individual's `multimedia()`.
|
|
9190
|
+
*/
|
|
9191
|
+
async collectMultimedia(options) {
|
|
9192
|
+
const people = [];
|
|
9193
|
+
if (options?.indiIds?.length) {
|
|
9194
|
+
options.indiIds.forEach((id) => {
|
|
9195
|
+
const indi = this.indi(id);
|
|
9196
|
+
if (indi) {
|
|
9197
|
+
people.push(indi);
|
|
9198
|
+
}
|
|
9199
|
+
});
|
|
9200
|
+
} else {
|
|
9201
|
+
this.indis()?.forEach((indi) => {
|
|
9202
|
+
if (indi) {
|
|
9203
|
+
people.push(indi);
|
|
9204
|
+
}
|
|
9205
|
+
});
|
|
9206
|
+
}
|
|
9207
|
+
const lists = await Promise.all(
|
|
9208
|
+
people.map((indi) => indi.multimedia(options?.namespace))
|
|
9209
|
+
);
|
|
9210
|
+
return mergeMediaLists(...lists);
|
|
9211
|
+
}
|
|
9212
|
+
/**
|
|
9213
|
+
* Serialize as GEDCOM 7 and pack a FamilySearch GEDZIP (`.gdz`).
|
|
9214
|
+
* Media bytes must be supplied by the caller (cache/fetch outside the parser).
|
|
9215
|
+
*/
|
|
9216
|
+
async toGedzip(options) {
|
|
9217
|
+
const text = this.toGedcom(void 0, 0, {
|
|
9218
|
+
...options,
|
|
9219
|
+
gedcomVersion: "7.0"
|
|
9220
|
+
});
|
|
9221
|
+
return buildGedzip(text, options?.media ?? []);
|
|
9222
|
+
}
|
|
7887
9223
|
objes() {
|
|
7888
9224
|
return this.getList("@@OBJE");
|
|
7889
9225
|
}
|
|
@@ -7968,9 +9304,52 @@ var GedCom = class extends Common {
|
|
|
7968
9304
|
});
|
|
7969
9305
|
return lists;
|
|
7970
9306
|
}
|
|
7971
|
-
|
|
9307
|
+
getGedcomVersion() {
|
|
9308
|
+
const raw = this.get("HEAD")?.get("GEDC")?.get("VERS")?.toValue();
|
|
9309
|
+
return normalizeGedcomVersion(
|
|
9310
|
+
typeof raw === "string" ? raw : void 0
|
|
9311
|
+
);
|
|
9312
|
+
}
|
|
9313
|
+
/** Rewrite HEAD.GEDC (and CHAR/FORM) for the requested export version. */
|
|
9314
|
+
applyExportVersion(version) {
|
|
9315
|
+
const head = this.get("HEAD");
|
|
9316
|
+
if (!head) {
|
|
9317
|
+
return;
|
|
9318
|
+
}
|
|
9319
|
+
this.applyGedcomSpecToHead(head, normalizeGedcomVersion(version));
|
|
9320
|
+
}
|
|
9321
|
+
applyGedcomSpecToHead(head, version) {
|
|
9322
|
+
const previousGedc = head.get("GEDC");
|
|
9323
|
+
const previousForm = previousGedc?.get("FORM")?.toValue();
|
|
9324
|
+
const previousChar = head.get("CHAR")?.toValue();
|
|
9325
|
+
head.remove("GEDC");
|
|
9326
|
+
const gedc = head.set("GEDC", "");
|
|
9327
|
+
if (!gedc) {
|
|
9328
|
+
return;
|
|
9329
|
+
}
|
|
9330
|
+
gedc.set("VERS", version);
|
|
9331
|
+
if (version === "7.0") {
|
|
9332
|
+
head.remove("CHAR");
|
|
9333
|
+
return;
|
|
9334
|
+
}
|
|
9335
|
+
gedc.set(
|
|
9336
|
+
"FORM",
|
|
9337
|
+
typeof previousForm === "string" && previousForm ? previousForm : "LINEAGE-LINKED"
|
|
9338
|
+
);
|
|
9339
|
+
if (!head.get("CHAR")?.toValue()) {
|
|
9340
|
+
head.set(
|
|
9341
|
+
"CHAR",
|
|
9342
|
+
typeof previousChar === "string" && previousChar ? previousChar : "UTF-8"
|
|
9343
|
+
);
|
|
9344
|
+
}
|
|
9345
|
+
}
|
|
9346
|
+
getDownloadHeader(gedcomVersion) {
|
|
7972
9347
|
const newHead = createCommon();
|
|
7973
9348
|
Object.assign(newHead, this.get("HEAD") ?? {});
|
|
9349
|
+
this.applyGedcomSpecToHead(
|
|
9350
|
+
newHead,
|
|
9351
|
+
gedcomVersion ?? this.getGedcomVersion()
|
|
9352
|
+
);
|
|
7974
9353
|
const existingSour = this.get("HEAD")?.get("SOUR");
|
|
7975
9354
|
const existingTreeName = existingSour?.get("_TREE")?.toValue();
|
|
7976
9355
|
const existingTreeUniqueId = existingSour?.get("_TID")?.toValue();
|
|
@@ -8017,22 +9396,45 @@ var GedCom = class extends Common {
|
|
|
8017
9396
|
}
|
|
8018
9397
|
toGedcom(tag, level, options) {
|
|
8019
9398
|
if (options?.super) {
|
|
8020
|
-
return appendGedcomTrailer(
|
|
8021
|
-
super.toGedcom(tag, level, options)
|
|
8022
|
-
);
|
|
9399
|
+
return appendGedcomTrailer(super.toGedcom(tag, level, options));
|
|
8023
9400
|
}
|
|
9401
|
+
const requestedVersion = options?.gedcomVersion;
|
|
9402
|
+
const exportVersion = requestedVersion ? normalizeGedcomVersion(requestedVersion) : this.getGedcomVersion();
|
|
9403
|
+
const exportOptions = {
|
|
9404
|
+
...options,
|
|
9405
|
+
obje: {
|
|
9406
|
+
standardize: options?.obje?.standardize ?? (requestedVersion !== void 0 || !options?.original),
|
|
9407
|
+
override: options?.obje?.override,
|
|
9408
|
+
namespace: options?.obje?.namespace
|
|
9409
|
+
}
|
|
9410
|
+
};
|
|
8024
9411
|
const newGedcom = createGedCom();
|
|
8025
9412
|
Object.assign(newGedcom, this);
|
|
8026
|
-
if (!
|
|
9413
|
+
if (!exportOptions.original) {
|
|
8027
9414
|
Object.assign(newGedcom, {
|
|
8028
|
-
HEAD: this.getDownloadHeader()
|
|
9415
|
+
HEAD: this.getDownloadHeader(exportVersion)
|
|
8029
9416
|
});
|
|
8030
9417
|
}
|
|
8031
|
-
if (
|
|
8032
|
-
const newContent = this.getIndiRelatedLists(
|
|
9418
|
+
if (exportOptions.indis?.length) {
|
|
9419
|
+
const newContent = this.getIndiRelatedLists(exportOptions.indis);
|
|
8033
9420
|
Object.assign(newGedcom, newContent);
|
|
8034
9421
|
}
|
|
8035
|
-
|
|
9422
|
+
const restoreEnums = exportVersion === "7.0" ? applyGedcom7Enumerations(newGedcom) : void 0;
|
|
9423
|
+
const restoreDates = exportVersion === "7.0" ? applyGedcom7DatePhrases(newGedcom) : void 0;
|
|
9424
|
+
const restoreMetadata = exportVersion === "7.0" ? applyGedcom7RecordMetadata(newGedcom) : void 0;
|
|
9425
|
+
const restoreSchema = exportVersion === "7.0" ? ensureExtensionSchema(newGedcom) : void 0;
|
|
9426
|
+
try {
|
|
9427
|
+
return newGedcom.toGedcom(tag, level, {
|
|
9428
|
+
...exportOptions,
|
|
9429
|
+
gedcomVersion: exportVersion,
|
|
9430
|
+
super: true
|
|
9431
|
+
});
|
|
9432
|
+
} finally {
|
|
9433
|
+
restoreSchema?.();
|
|
9434
|
+
restoreMetadata?.();
|
|
9435
|
+
restoreDates?.();
|
|
9436
|
+
restoreEnums?.();
|
|
9437
|
+
}
|
|
8036
9438
|
}
|
|
8037
9439
|
hasTag(tag) {
|
|
8038
9440
|
const tagName = typeof tag === "string" ? tag : tag?.get("NAME")?.toValue();
|
|
@@ -8511,20 +9913,6 @@ var mergeGedcoms = (targetGedcom, sourceGedcom, strategy = "id") => {
|
|
|
8511
9913
|
return mergedGedcom;
|
|
8512
9914
|
};
|
|
8513
9915
|
|
|
8514
|
-
// src/classes/objes.ts
|
|
8515
|
-
var Objects = class _Objects extends List {
|
|
8516
|
-
copy() {
|
|
8517
|
-
const newList = new _Objects();
|
|
8518
|
-
this.entries().forEach(([key, value]) => {
|
|
8519
|
-
newList.item(key, value);
|
|
8520
|
-
});
|
|
8521
|
-
return newList;
|
|
8522
|
-
}
|
|
8523
|
-
except(item) {
|
|
8524
|
-
return this.copy().delete(item);
|
|
8525
|
-
}
|
|
8526
|
-
};
|
|
8527
|
-
|
|
8528
9916
|
// src/classes/repos.ts
|
|
8529
9917
|
var Repositories = class _Repositories extends List {
|
|
8530
9918
|
copy() {
|
|
@@ -8567,144 +9955,6 @@ var Submitters = class _Submitters extends List {
|
|
|
8567
9955
|
}
|
|
8568
9956
|
};
|
|
8569
9957
|
|
|
8570
|
-
// src/classes/note.ts
|
|
8571
|
-
var CommonNote = class extends Common {
|
|
8572
|
-
constructor(gedcom, id, main, parent) {
|
|
8573
|
-
super(gedcom, id, main, parent);
|
|
8574
|
-
delete this.id;
|
|
8575
|
-
}
|
|
8576
|
-
set value(value) {
|
|
8577
|
-
const [note, ...contents] = value?.split(/\r?\n/) ?? [];
|
|
8578
|
-
this._value = note;
|
|
8579
|
-
if (contents.length) {
|
|
8580
|
-
const newContents = new List();
|
|
8581
|
-
contents.forEach((c, i) => {
|
|
8582
|
-
const newContent = createCommon(
|
|
8583
|
-
this._gedcom,
|
|
8584
|
-
void 0,
|
|
8585
|
-
this.main
|
|
8586
|
-
);
|
|
8587
|
-
newContent.id = `@U${i}@`;
|
|
8588
|
-
newContent.value = c;
|
|
8589
|
-
newContents.append(newContent);
|
|
8590
|
-
});
|
|
8591
|
-
const firstItem = newContents.index(0);
|
|
8592
|
-
if (firstItem) {
|
|
8593
|
-
if (newContents.length === 1) {
|
|
8594
|
-
this.set("CONT", firstItem);
|
|
8595
|
-
} else {
|
|
8596
|
-
this.set("CONT", newContents);
|
|
8597
|
-
}
|
|
8598
|
-
}
|
|
8599
|
-
}
|
|
8600
|
-
}
|
|
8601
|
-
get value() {
|
|
8602
|
-
const contents = this.get("CONT")?.toList().map((content) => content.value).join("\n");
|
|
8603
|
-
if (contents) {
|
|
8604
|
-
return `${this._value}
|
|
8605
|
-
${contents}`;
|
|
8606
|
-
}
|
|
8607
|
-
return this._value;
|
|
8608
|
-
}
|
|
8609
|
-
exportValue() {
|
|
8610
|
-
return this._value;
|
|
8611
|
-
}
|
|
8612
|
-
};
|
|
8613
|
-
var createCommonNote = (gedcom, id, main, parent) => {
|
|
8614
|
-
return createProxy(
|
|
8615
|
-
new CommonNote(gedcom, id, main, parent)
|
|
8616
|
-
);
|
|
8617
|
-
};
|
|
8618
|
-
|
|
8619
|
-
// src/classes/obje.ts
|
|
8620
|
-
var Obje = class extends Common {
|
|
8621
|
-
standardizeMedia(namespace, override = true, urlGetter) {
|
|
8622
|
-
if (!this._gedcom) {
|
|
8623
|
-
return this;
|
|
8624
|
-
}
|
|
8625
|
-
const rin = this?.get("RIN")?.toValue();
|
|
8626
|
-
const clone = this?.get("_CLON._OID")?.toValue();
|
|
8627
|
-
const mser = this?.get("_MSER._LKID")?.toValue();
|
|
8628
|
-
const title = this?.get("FILE.TITL")?.toValue() ?? this?.get("TITL")?.toValue() ?? "";
|
|
8629
|
-
const note = this?.get("FILE.NOTE")?.toValue() ?? this?.get("NOTE")?.toValue() ?? "";
|
|
8630
|
-
const form = this?.get("FILE.FORM")?.toValue();
|
|
8631
|
-
const file = this?.get("FILE")?.toValue();
|
|
8632
|
-
const imgId = rin || clone || mser;
|
|
8633
|
-
const url = file || namespace && urlGetter?.(namespace, imgId);
|
|
8634
|
-
if (!url) {
|
|
8635
|
-
return this;
|
|
8636
|
-
}
|
|
8637
|
-
const newObject = createObje(this._gedcom, this.id, this.main);
|
|
8638
|
-
if (!override) {
|
|
8639
|
-
Object.assign(newObject, this);
|
|
8640
|
-
}
|
|
8641
|
-
if (form) {
|
|
8642
|
-
if (typeof form === "string") {
|
|
8643
|
-
const newForm = createCommon(
|
|
8644
|
-
this._gedcom,
|
|
8645
|
-
void 0,
|
|
8646
|
-
this.main
|
|
8647
|
-
);
|
|
8648
|
-
newForm.value = form;
|
|
8649
|
-
newObject.set("FORM", newForm);
|
|
8650
|
-
} else {
|
|
8651
|
-
newObject.set("FORM", form);
|
|
8652
|
-
}
|
|
8653
|
-
}
|
|
8654
|
-
if (title) {
|
|
8655
|
-
if (typeof title === "string") {
|
|
8656
|
-
const newTitle = createCommon(
|
|
8657
|
-
this._gedcom,
|
|
8658
|
-
void 0,
|
|
8659
|
-
this.main
|
|
8660
|
-
);
|
|
8661
|
-
newTitle.value = title;
|
|
8662
|
-
newObject.set("TITL", newTitle);
|
|
8663
|
-
if (!note) {
|
|
8664
|
-
newObject.set("NOTE", newTitle);
|
|
8665
|
-
}
|
|
8666
|
-
} else {
|
|
8667
|
-
newObject.set("TITL", title);
|
|
8668
|
-
if (!note) {
|
|
8669
|
-
newObject.set("NOTE", title);
|
|
8670
|
-
}
|
|
8671
|
-
}
|
|
8672
|
-
}
|
|
8673
|
-
if (note) {
|
|
8674
|
-
if (typeof note === "string") {
|
|
8675
|
-
const newNote = createCommon(
|
|
8676
|
-
this._gedcom,
|
|
8677
|
-
void 0,
|
|
8678
|
-
this.main
|
|
8679
|
-
);
|
|
8680
|
-
newNote.value = note;
|
|
8681
|
-
newObject.set("NOTE", newNote);
|
|
8682
|
-
if (!title) {
|
|
8683
|
-
newObject.set("TITL", newNote);
|
|
8684
|
-
}
|
|
8685
|
-
} else {
|
|
8686
|
-
newObject.set("NOTE", note);
|
|
8687
|
-
if (!title) {
|
|
8688
|
-
newObject.set("TITL", note);
|
|
8689
|
-
}
|
|
8690
|
-
}
|
|
8691
|
-
}
|
|
8692
|
-
const newUrl = createCommon(this._gedcom, void 0, this.main);
|
|
8693
|
-
newUrl.value = url;
|
|
8694
|
-
newObject.set("FILE", newUrl);
|
|
8695
|
-
if (override) {
|
|
8696
|
-
Object.assign(this, newObject);
|
|
8697
|
-
return this;
|
|
8698
|
-
}
|
|
8699
|
-
return newObject;
|
|
8700
|
-
}
|
|
8701
|
-
};
|
|
8702
|
-
var createObje = (gedcom, id, main, parent) => {
|
|
8703
|
-
return createProxy(
|
|
8704
|
-
new Obje(gedcom, id, main, parent)
|
|
8705
|
-
);
|
|
8706
|
-
};
|
|
8707
|
-
|
|
8708
9958
|
// src/classes/repo.ts
|
|
8709
9959
|
var Repo = class extends Common {
|
|
8710
9960
|
};
|
|
@@ -8753,6 +10003,8 @@ var create = (gedcom, type, id, nodes) => {
|
|
|
8753
10003
|
prevNode = createIndi(gedcom, id);
|
|
8754
10004
|
} else if (convertType === "FAM") {
|
|
8755
10005
|
prevNode = createFam(gedcom, id);
|
|
10006
|
+
} else if (convertType === "SNOTE" || convertType === "NOTE") {
|
|
10007
|
+
prevNode = createCommonNote(gedcom, id);
|
|
8756
10008
|
} else {
|
|
8757
10009
|
prevNode = createCommon(gedcom, id);
|
|
8758
10010
|
}
|
|
@@ -8768,7 +10020,7 @@ var create = (gedcom, type, id, nodes) => {
|
|
|
8768
10020
|
prevNode = createObje(gedcom, void 0, mainNode, curNode);
|
|
8769
10021
|
} else if (type === "DATE") {
|
|
8770
10022
|
prevNode = createCommonDate(gedcom, void 0, mainNode, curNode);
|
|
8771
|
-
} else if (type === "NOTE") {
|
|
10023
|
+
} else if (type === "NOTE" || type === "SNOTE") {
|
|
8772
10024
|
prevNode = createCommonNote(gedcom, void 0, mainNode, curNode);
|
|
8773
10025
|
} else if (type === "NAME" && mainNode instanceof Indi) {
|
|
8774
10026
|
prevNode = createCommonName(gedcom, void 0, mainNode, curNode);
|
|
@@ -8851,6 +10103,13 @@ var GedcomTree = {
|
|
|
8851
10103
|
if (linesAcc._inHead && lineIndent === 1 && lineType === "FILE") {
|
|
8852
10104
|
linesAcc._hasFile = true;
|
|
8853
10105
|
}
|
|
10106
|
+
if (lineType.toUpperCase() === "CONC") {
|
|
10107
|
+
const last = acc[acc.length - 1];
|
|
10108
|
+
if (last !== void 0) {
|
|
10109
|
+
acc[acc.length - 1] = `${last}${lineValue}`;
|
|
10110
|
+
return acc;
|
|
10111
|
+
}
|
|
10112
|
+
}
|
|
8854
10113
|
if (lineIndent > 0 && lineIndent > prevLineIndent && lineValue && isId(lineValue)) {
|
|
8855
10114
|
const refLines = lineValue.split(/,\s*/).map((id) => line.replace(lineValue, id));
|
|
8856
10115
|
if (refLines.length > 1) {
|
|
@@ -9049,4 +10308,4 @@ var createEmptyGedcom = (options) => {
|
|
|
9049
10308
|
return gedcom;
|
|
9050
10309
|
};
|
|
9051
10310
|
|
|
9052
|
-
export { ACCEPTED_DATE_FORMATS, ACCEPTED_DATE_FORMATS_REGEX, ADOPTED, APP_BRANDING, BIOLOGICAL, BIRTH, BIRTH_ASC, BIRTH_DESC, Common, CommonDate, CommonName, CommonNote, CustomTags, DATE_ASC, DATE_DESC, DEATH_ASC, DEATH_DESC, DEFAULT, EVERY, Existed, FEMALE, FOSTER, FRIEND, Fam, Families, GedCom, parser_default as GedcomTree, ID_GETTER_REG, ID_REG, ID_SPLIT_REG, Indi, Individuals, KinshipTranslator, KinshipTranslatorBasic, KinshipTranslatorDe as KinshipTranslatorDE, KinshipTranslatorEn as KinshipTranslatorEN, KinshipTranslatorEs as KinshipTranslatorES, KinshipTranslatorFr as KinshipTranslatorFR, KinshipTranslatorHU, KinshipTranslatorRu as KinshipTranslatorRU, LINE_REG, List, MALE, MAX_FILE_SIZE_TO_SYNC, ORIG_HEAD_TAG, OTHER, Obje, Objects, PARTNER, PEDIGREE_VALUES, PartnerType, PlaceType, REF_LINE_REG, Range, RelationType, Repo, Repositories, SEALING, SINGLE, SPOUSE, STEP, Sour, Sources, Subm, Submitters, UNKOWN, addFamilyFact, addIndividualFact, attachChildToFamily, attachSpouseToFamily, cacheDiscoveredPath, canAttachAsSpouse, commonDateFormatter, create, createCommon, createCommonDate, createCommonName, createCommonNote, createEmptyGedcom, createFam, createGedCom, createIndi, createObje, createProxy, createRepo, createSour, createSubm, dateFormatter, parser_default as default, extractSeparationYears, extractSplitPoints, familyHasChild, familyHasParent, findMatchingRangeForSplitRange, findReusableParentChildFamily, firstPointerId, fromTuple, generateSplitRanges, getAllProp, getBirthAsc, getCacheManagerFactory, getDateLocale, getFamilyWith, getI18n, getKinshipTranslatorClass, getListTag, getMarriageAsc, getMarriageAscAndBirth, getMarriageAscAndChildBirth, getName, getNameAsc, getNameAscAndBirth, getNameDesc, getPlaceParserProvider, getPlaceParts, getPlaceTranslatorProvider, getPlaces, getRawSize, getValidKey, getValidKeys, getValidTag, getVersion, hungarianOrdinalize, i18n, idGetter, implemented, inRange, initializeCache, isCommonDate, isDevelopment, isGedcomString, isId, isIntersectedRange, isOnlyMainProp, isRangeContained, isValidKey, makePointer, marriageDateFormatter, mergeGedcoms, nameFormatter, nextRecordId, notImplemented, noteDateFormatter, ordinalize, parseRangeBounds, pathCache, placeTranslator, pointerIds, profilePictureCache, relativesCache, resetCacheManagerFactory, resetDateLocaleProvider, resetI18nProvider, resetKinshipTranslatorClass, resetPlaceParserProvider, resetPlaceTranslatorProvider, resetRelativesCache, setCacheManagerFactory, setCauseOfDeath, setChildPedigree, setDateLocaleProvider, setDeceased, setFamilyMarriage, setI18nProvider, setKinshipTranslatorClass, setNestedGroup, setPlaceParserProvider, setPlaceTranslatorProvider, splitOverlappingRanges, splitRange, spouseTagFor, toGedcomPedigree, translators_exports as translators, updateFactRecord, validateGedcomContent };
|
|
10311
|
+
export { ACCEPTED_DATE_FORMATS, ACCEPTED_DATE_FORMATS_REGEX, ADOPTED, APP_BRANDING, BIOLOGICAL, BIRTH, BIRTH_ASC, BIRTH_DESC, Common, CommonDate, CommonName, CommonNote, CustomTags, DATE_ASC, DATE_DESC, DEATH_ASC, DEATH_DESC, DEFAULT, DEFAULT_GEDCOM_EXPORT_VERSION, EVERY, Existed, FEMALE, FOSTER, FRIEND, Fam, Families, GEDCOM7_CALENDARS, GEDCOM7_PEDI_VALUES, GEDCOM7_RESN_VALUES, GEDCOM7_ROLE_VALUES, GEDCOM7_SEX_VALUES, GEDCOM_EXPORT_VERSIONS, GEDZIP_EXTENSION, GEDZIP_GEDCOM_ENTRY, GEDZIP_MIME, GedCom, parser_default as GedcomTree, ID_GETTER_REG, ID_REG, ID_SPLIT_REG, Indi, Individuals, KinshipTranslator, KinshipTranslatorBasic, KinshipTranslatorDe as KinshipTranslatorDE, KinshipTranslatorEn as KinshipTranslatorEN, KinshipTranslatorEs as KinshipTranslatorES, KinshipTranslatorFr as KinshipTranslatorFR, KinshipTranslatorHU, KinshipTranslatorRu as KinshipTranslatorRU, LINE_REG, List, MALE, MAX_FILE_SIZE_TO_SYNC, ORIG_HEAD_TAG, OTHER, Obje, Objects, PARTNER, PEDIGREE_VALUES, PartnerType, PlaceType, REF_LINE_REG, Range, RelationType, Repo, Repositories, SEALING, SINGLE, SPOUSE, STEP, Sour, Sources, Subm, Submitters, TREEVIZ_EXTENSION_BASE_URI, TREEVIZ_EXTENSION_URIS, UNKOWN, addFamilyFact, addIndividualFact, addNonEvent, applyGedcom7DatePhrases, applyGedcom7Enumerations, applyGedcom7RecordMetadata, attachChildToFamily, attachSpouseToFamily, buildGedzip, buildGedzipBlob, bytesToDataUrl, cacheDiscoveredPath, canAttachAsSpouse, collectExtensionTagsFrom, commonDateFormatter, create, createCommon, createCommonDate, createCommonName, createCommonNote, createEmptyGedcom, createFam, createGedCom, createGedcomUid, createIndi, createObje, createProxy, createRepo, createSour, createSubm, dateFormatter, parser_default as default, downloadGedzipMedia, ensureExtensionSchema, extractGedzip, extractGedzipGedcom, extractSeparationYears, extractSplitPoints, familyHasChild, familyHasParent, findMatchingRangeForSplitRange, findReusableParentChildFamily, firstPointerId, formatGedcom7Timestamp, fromTuple, generateSplitRanges, getAllProp, getBirthAsc, getCacheManagerFactory, getDateLocale, getExtensionSchema, getFamilyWith, getFileExtension, getI18n, getKinshipTranslatorClass, getListTag, getMarriageAsc, getMarriageAscAndBirth, getMarriageAscAndChildBirth, getName, getNameAsc, getNameAscAndBirth, getNameDesc, getPlaceParserProvider, getPlaceParts, getPlaceTranslatorProvider, getPlaces, getRawSize, getValidKey, getValidKeys, getValidTag, getVersion, hungarianOrdinalize, i18n, idGetter, implemented, inRange, inferMediaForm, initializeCache, isCommonDate, isDevelopment, isGedcom7, isGedcomString, isGedzipContainer, isId, isImageFormat, isIntersectedRange, isObjePointer, isOnlyMainProp, isRangeContained, isRemoteOrEmbeddedMediaUrl, isValidKey, makePointer, marriageDateFormatter, mergeGedcoms, mergeMediaLists, nameFormatter, nextRecordId, normalizeGedcomVersion, notImplemented, noteDateFormatter, ordinalize, parseGedcom7CalendarPrefix, parseRangeBounds, pathCache, placeTranslator, pointerIds, profilePictureCache, registerExtensionTag, relativesCache, remountGedzipMediaAsDataUrls, resetCacheManagerFactory, resetDateLocaleProvider, resetI18nProvider, resetKinshipTranslatorClass, resetPlaceParserProvider, resetPlaceTranslatorProvider, resetRelativesCache, resolveLocalMediaUrl, resolveMediaContent, resolveObjeForm, rewriteGedcomFilePaths, setCacheManagerFactory, setCauseOfDeath, setChildPedigree, setDateLocaleProvider, setDeceased, setFamilyMarriage, setI18nProvider, setKinshipTranslatorClass, setLocalMediaResolver, setMediaContentResolver, setNestedGroup, setPlaceParserProvider, setPlaceTranslatorProvider, splitOverlappingRanges, splitRange, spouseTagFor, toGedcomPedigree, translators_exports as translators, updateFactRecord, validateGedcomContent, withGedcom7Calendar };
|