@treeviz/gedcom-parser 2.0.12 → 2.1.0
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
|
@@ -2226,11 +2226,17 @@ var List = class _List {
|
|
|
2226
2226
|
const gedcom = [];
|
|
2227
2227
|
this.entries().forEach(([_, item]) => {
|
|
2228
2228
|
const validTag = getValidTag(tag);
|
|
2229
|
-
const
|
|
2230
|
-
const
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2229
|
+
const xref = item.id;
|
|
2230
|
+
const payload = item.exportValue?.();
|
|
2231
|
+
if (xref) {
|
|
2232
|
+
gedcom.push(
|
|
2233
|
+
`${level} ${xref} ${validTag}${payload ? ` ${payload}` : ""}`
|
|
2234
|
+
);
|
|
2235
|
+
} else {
|
|
2236
|
+
gedcom.push(
|
|
2237
|
+
`${level} ${validTag}${payload ? ` ${payload}` : ""}`
|
|
2238
|
+
);
|
|
2239
|
+
}
|
|
2234
2240
|
gedcom.push(
|
|
2235
2241
|
...item.toGedcomLines(
|
|
2236
2242
|
validTag,
|
|
@@ -2488,12 +2494,14 @@ var Common = class _Common {
|
|
|
2488
2494
|
);
|
|
2489
2495
|
}
|
|
2490
2496
|
standardizeObject(tag, options) {
|
|
2491
|
-
if (tag === "OBJE" &&
|
|
2497
|
+
if (tag === "OBJE" && options?.obje?.standardize && "standardizeMedia" in this) {
|
|
2492
2498
|
const standardize = this.standardizeMedia;
|
|
2493
2499
|
return standardize.call(
|
|
2494
2500
|
this,
|
|
2495
2501
|
options.obje.namespace,
|
|
2496
|
-
options.obje.override
|
|
2502
|
+
options.obje.override,
|
|
2503
|
+
void 0,
|
|
2504
|
+
options.gedcomVersion
|
|
2497
2505
|
);
|
|
2498
2506
|
}
|
|
2499
2507
|
}
|
|
@@ -2520,7 +2528,7 @@ var Common = class _Common {
|
|
|
2520
2528
|
if (typeof prop?.toObject === "function") {
|
|
2521
2529
|
if (prop instanceof _Common) {
|
|
2522
2530
|
json[validKey] = prop.toObject(validKey, options);
|
|
2523
|
-
} else {
|
|
2531
|
+
} else if (prop instanceof List) {
|
|
2524
2532
|
json = {
|
|
2525
2533
|
...json,
|
|
2526
2534
|
...prop.toObject(validKey, options)
|
|
@@ -2578,8 +2586,12 @@ var Common = class _Common {
|
|
|
2578
2586
|
this.standardizeObject(tag, options);
|
|
2579
2587
|
const validKeys = getValidKeys(this);
|
|
2580
2588
|
const gedcom = [];
|
|
2589
|
+
const isGedcom7Export = options?.gedcomVersion === "7.0";
|
|
2581
2590
|
validKeys.forEach((key) => {
|
|
2582
2591
|
const validKey = key;
|
|
2592
|
+
if (isGedcom7Export && validKey === "CONC") {
|
|
2593
|
+
return;
|
|
2594
|
+
}
|
|
2583
2595
|
const prop = this.get(validKey);
|
|
2584
2596
|
if (typeof prop?.toGedcomLines === "function") {
|
|
2585
2597
|
if (prop instanceof _Common) {
|
|
@@ -2590,7 +2602,7 @@ var Common = class _Common {
|
|
|
2590
2602
|
gedcom.push(
|
|
2591
2603
|
...prop.toGedcomLines(validKey, level + 1, options)
|
|
2592
2604
|
);
|
|
2593
|
-
} else {
|
|
2605
|
+
} else if (prop instanceof List) {
|
|
2594
2606
|
gedcom.push(
|
|
2595
2607
|
...prop.toGedcomLines(validKey, level, options)
|
|
2596
2608
|
);
|
|
@@ -2931,7 +2943,11 @@ var STANDARD_QUALIFIERS = {
|
|
|
2931
2943
|
BEF: "Bef.",
|
|
2932
2944
|
BEFORE: "Bef.",
|
|
2933
2945
|
AFT: "Aft.",
|
|
2934
|
-
AFTER: "Aft."
|
|
2946
|
+
AFTER: "Aft.",
|
|
2947
|
+
CAL: "Abt.",
|
|
2948
|
+
// calculated ≈ about for display
|
|
2949
|
+
EST: "Abt."
|
|
2950
|
+
// estimated ≈ about for display
|
|
2935
2951
|
};
|
|
2936
2952
|
var EXPORT_QUALIFIERS = {
|
|
2937
2953
|
"Abt.": "ABT",
|
|
@@ -2939,6 +2955,11 @@ var EXPORT_QUALIFIERS = {
|
|
|
2939
2955
|
"Aft.": "AFT"
|
|
2940
2956
|
};
|
|
2941
2957
|
var GEDCOM_MONTHS = /\b(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\b/g;
|
|
2958
|
+
var CALENDAR_PREFIX = /^(?<calendar>GREGORIAN|JULIAN|FRENCH_R|HEBREW)\b\s+/i;
|
|
2959
|
+
var isGedcomDateValueForm = (value) => (
|
|
2960
|
+
// Require space/end after the token so display forms like "Abt." are not opaque.
|
|
2961
|
+
/^(FROM|TO|BET|AFT|BEF|ABT|CAL|EST|INT)(\s|$)/i.test(value) || /\bAND\b/i.test(value)
|
|
2962
|
+
);
|
|
2942
2963
|
var NOTE_MARKER = "####";
|
|
2943
2964
|
var formatDateWithComponents = (date, hasDay, hasMonth, hasYear, noteValue, baseFormat = "dd MMM yyyy", locale) => {
|
|
2944
2965
|
const hasNote = baseFormat.includes("NOTE");
|
|
@@ -2963,29 +2984,45 @@ var CommonDate = class extends Common {
|
|
|
2963
2984
|
super(gedcom, id, main, parent);
|
|
2964
2985
|
delete this.id;
|
|
2965
2986
|
}
|
|
2987
|
+
get calendar() {
|
|
2988
|
+
return this._calendar;
|
|
2989
|
+
}
|
|
2966
2990
|
set value(value) {
|
|
2967
2991
|
if (value) {
|
|
2968
|
-
const noteRegExp = /^(?<note>[a-zA-Z]+\.)/;
|
|
2969
|
-
const noteMatch = value.match(noteRegExp)?.groups;
|
|
2970
2992
|
let validValue = value;
|
|
2993
|
+
const calendarMatch = validValue.match(CALENDAR_PREFIX);
|
|
2994
|
+
if (calendarMatch?.groups?.calendar) {
|
|
2995
|
+
this._calendar = calendarMatch.groups.calendar.toUpperCase();
|
|
2996
|
+
validValue = validValue.slice(calendarMatch[0].length);
|
|
2997
|
+
} else {
|
|
2998
|
+
this._calendar = void 0;
|
|
2999
|
+
}
|
|
3000
|
+
const noteRegExp = /^(?<note>[a-zA-Z]+\.)/;
|
|
3001
|
+
const noteMatch = validValue.match(noteRegExp)?.groups;
|
|
2971
3002
|
if (noteMatch?.note) {
|
|
2972
3003
|
this.NOTE = this.NOTE || createCommon(this._gedcom, void 0, this.main);
|
|
2973
3004
|
this.NOTE.value = noteMatch?.note;
|
|
2974
|
-
validValue =
|
|
3005
|
+
validValue = validValue.replace(noteRegExp, "");
|
|
2975
3006
|
} else {
|
|
2976
|
-
const qualifierMatch =
|
|
2977
|
-
/^(?<qualifier>ABT|ABOUT|BEF|BEFORE|AFT|AFTER)\b\s*/i
|
|
3007
|
+
const qualifierMatch = validValue.match(
|
|
3008
|
+
/^(?<qualifier>ABT|ABOUT|BEF|BEFORE|AFT|AFTER|CAL|EST)\b\s*/i
|
|
2978
3009
|
);
|
|
2979
3010
|
const qualifier = qualifierMatch?.groups?.qualifier?.toUpperCase();
|
|
2980
3011
|
const note = qualifier ? STANDARD_QUALIFIERS[qualifier] : void 0;
|
|
2981
3012
|
if (note) {
|
|
2982
3013
|
this.NOTE = this.NOTE || createCommon(this._gedcom, void 0, this.main);
|
|
2983
3014
|
this.NOTE.value = note;
|
|
2984
|
-
validValue =
|
|
3015
|
+
validValue = validValue.slice(qualifierMatch[0].length);
|
|
2985
3016
|
}
|
|
2986
3017
|
}
|
|
2987
3018
|
const acceptedDate = this.isValidDateFormat(validValue);
|
|
2988
|
-
if (
|
|
3019
|
+
if (isGedcomDateValueForm(validValue.trim())) {
|
|
3020
|
+
delete this.DAY;
|
|
3021
|
+
delete this.MONTH;
|
|
3022
|
+
delete this.YEAR;
|
|
3023
|
+
this._date = void 0;
|
|
3024
|
+
this._value = value;
|
|
3025
|
+
} else if (acceptedDate) {
|
|
2989
3026
|
this.DAY = this.DAY || createCommon(this._gedcom, void 0, this.main);
|
|
2990
3027
|
this.DAY.value = format(acceptedDate, "dd");
|
|
2991
3028
|
this.MONTH = this.MONTH || createCommon(this._gedcom, void 0, this.main);
|
|
@@ -3088,6 +3125,15 @@ var CommonDate = class extends Common {
|
|
|
3088
3125
|
);
|
|
3089
3126
|
}
|
|
3090
3127
|
exportValue() {
|
|
3128
|
+
if (typeof this._value === "string") {
|
|
3129
|
+
const withoutCalendar = this._value.replace(CALENDAR_PREFIX, "");
|
|
3130
|
+
if (isGedcomDateValueForm(withoutCalendar.trim())) {
|
|
3131
|
+
return this._value.replace(
|
|
3132
|
+
/^((?:GREGORIAN|JULIAN|FRENCH_R|HEBREW)\s+)?(FROM|TO|BET|AFT|BEF|ABT|CAL|EST|INT)\b/i,
|
|
3133
|
+
(_m, cal, q) => `${cal || ""}${q.toUpperCase()}`
|
|
3134
|
+
);
|
|
3135
|
+
}
|
|
3136
|
+
}
|
|
3091
3137
|
const formatted = this.toValue("NOTE dd MMM yyyy", null);
|
|
3092
3138
|
if (!formatted) {
|
|
3093
3139
|
return formatted;
|
|
@@ -3095,10 +3141,14 @@ var CommonDate = class extends Common {
|
|
|
3095
3141
|
const note = this.NOTE?.value?.trim();
|
|
3096
3142
|
const qualifier = note ? EXPORT_QUALIFIERS[note] : void 0;
|
|
3097
3143
|
const standardized = qualifier ? formatted.replace(note, qualifier) : formatted;
|
|
3098
|
-
|
|
3144
|
+
const withMonths = standardized.replace(
|
|
3099
3145
|
GEDCOM_MONTHS,
|
|
3100
3146
|
(month) => month.toUpperCase()
|
|
3101
3147
|
);
|
|
3148
|
+
if (this._calendar && this._calendar !== "GREGORIAN") {
|
|
3149
|
+
return `${this._calendar} ${withMonths}`;
|
|
3150
|
+
}
|
|
3151
|
+
return withMonths;
|
|
3102
3152
|
}
|
|
3103
3153
|
toGedcomLines(tag, level = 0, options) {
|
|
3104
3154
|
const internal = new RegExp(
|
|
@@ -3630,6 +3680,24 @@ var addFamilyFact = (fam, input) => {
|
|
|
3630
3680
|
fillFact(gedcom, fam, event, input);
|
|
3631
3681
|
return event;
|
|
3632
3682
|
};
|
|
3683
|
+
var addNonEvent = (owner, input) => {
|
|
3684
|
+
const gedcom = owner.getGedcom();
|
|
3685
|
+
const eventType = input.event?.trim().toUpperCase();
|
|
3686
|
+
if (!gedcom || !eventType) {
|
|
3687
|
+
return void 0;
|
|
3688
|
+
}
|
|
3689
|
+
const no = createCommon(gedcom, void 0, owner);
|
|
3690
|
+
no.type = "NO";
|
|
3691
|
+
no.value = eventType;
|
|
3692
|
+
if (input.date?.trim()) {
|
|
3693
|
+
setDateOn(gedcom, owner, no, input.date);
|
|
3694
|
+
}
|
|
3695
|
+
if (input.note?.trim()) {
|
|
3696
|
+
no.set("NOTE", input.note.trim());
|
|
3697
|
+
}
|
|
3698
|
+
owner.assign("NO", no);
|
|
3699
|
+
return no;
|
|
3700
|
+
};
|
|
3633
3701
|
|
|
3634
3702
|
// src/utils/family-edit.ts
|
|
3635
3703
|
var PEDIGREE_VALUES = [
|
|
@@ -3856,16 +3924,58 @@ var getPlaces = (common, type = ["ALL" /* All */], maxLevel = 1, level = 0, main
|
|
|
3856
3924
|
});
|
|
3857
3925
|
return places;
|
|
3858
3926
|
};
|
|
3927
|
+
|
|
3928
|
+
// src/utils/local-media.ts
|
|
3929
|
+
var localMediaResolver;
|
|
3930
|
+
var isRemoteOrEmbeddedMediaUrl = (path) => {
|
|
3931
|
+
if (!path) {
|
|
3932
|
+
return false;
|
|
3933
|
+
}
|
|
3934
|
+
return path.startsWith("data:") || path.startsWith("blob:") || /^https?:\/\//i.test(path);
|
|
3935
|
+
};
|
|
3936
|
+
var resolveLocalMediaUrl = async (path) => {
|
|
3937
|
+
if (!path) {
|
|
3938
|
+
return void 0;
|
|
3939
|
+
}
|
|
3940
|
+
if (isRemoteOrEmbeddedMediaUrl(path)) {
|
|
3941
|
+
return path;
|
|
3942
|
+
}
|
|
3943
|
+
const resolved = await localMediaResolver?.(path);
|
|
3944
|
+
return resolved;
|
|
3945
|
+
};
|
|
3859
3946
|
var implemented = (type, ...args) => {
|
|
3860
3947
|
};
|
|
3861
3948
|
|
|
3862
3949
|
// src/utils/media-utils.ts
|
|
3863
3950
|
var getFileExtension = (filename) => {
|
|
3864
|
-
|
|
3865
|
-
|
|
3951
|
+
if (!filename) {
|
|
3952
|
+
return "";
|
|
3953
|
+
}
|
|
3954
|
+
if (filename.startsWith("data:")) {
|
|
3955
|
+
const mime = filename.slice(5).split(";")[0] || "";
|
|
3956
|
+
const subtype = (mime.split("/")[1] || "").toLowerCase();
|
|
3957
|
+
if (subtype === "jpeg") {
|
|
3958
|
+
return "jpg";
|
|
3959
|
+
}
|
|
3960
|
+
return subtype.split("+")[0] || "";
|
|
3961
|
+
}
|
|
3962
|
+
const withoutQuery = filename.split(/[?#]/)[0] || filename;
|
|
3963
|
+
const match = withoutQuery.match(/\.([^.]+)$/);
|
|
3964
|
+
return match ? match[1].toLowerCase() : "";
|
|
3866
3965
|
};
|
|
3867
3966
|
var isImageFormat = (format2) => {
|
|
3868
|
-
if (!format2)
|
|
3967
|
+
if (!format2) {
|
|
3968
|
+
return false;
|
|
3969
|
+
}
|
|
3970
|
+
let normalized = format2.toLowerCase().trim();
|
|
3971
|
+
if (normalized.startsWith("data:")) {
|
|
3972
|
+
normalized = getFileExtension(normalized);
|
|
3973
|
+
} else if (normalized.includes("/")) {
|
|
3974
|
+
normalized = normalized.split("/")[1]?.split("+")[0] || "";
|
|
3975
|
+
if (normalized === "jpeg") {
|
|
3976
|
+
normalized = "jpg";
|
|
3977
|
+
}
|
|
3978
|
+
}
|
|
3869
3979
|
const imageFormats = [
|
|
3870
3980
|
"jpg",
|
|
3871
3981
|
"jpeg",
|
|
@@ -3877,7 +3987,11 @@ var isImageFormat = (format2) => {
|
|
|
3877
3987
|
"tiff",
|
|
3878
3988
|
"tif"
|
|
3879
3989
|
];
|
|
3880
|
-
return imageFormats.includes(
|
|
3990
|
+
return imageFormats.includes(normalized);
|
|
3991
|
+
};
|
|
3992
|
+
var resolveObjeForm = (obje) => {
|
|
3993
|
+
const value = obje?.get?.("FILE.FORM")?.toValue?.() ?? obje?.get?.("FORM")?.toValue?.();
|
|
3994
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
3881
3995
|
};
|
|
3882
3996
|
var uniqueItemsCache = /* @__PURE__ */ new WeakMap();
|
|
3883
3997
|
var setNestedGroup = (obj, key, value, uniqueCounting = true) => {
|
|
@@ -4447,6 +4561,9 @@ var Fam = class extends Common {
|
|
|
4447
4561
|
addFact(input) {
|
|
4448
4562
|
return addFamilyFact(this, input);
|
|
4449
4563
|
}
|
|
4564
|
+
addNonEvent(input) {
|
|
4565
|
+
return addNonEvent(this, input);
|
|
4566
|
+
}
|
|
4450
4567
|
toList() {
|
|
4451
4568
|
return new Families().concat(
|
|
4452
4569
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -5165,10 +5282,14 @@ var Indi = class extends Common {
|
|
|
5165
5282
|
const clone = obje?.get("_CLON._OID")?.toValue();
|
|
5166
5283
|
const mser = obje?.get("_MSER._LKID")?.toValue();
|
|
5167
5284
|
let url = obje?.get("FILE")?.toValue();
|
|
5168
|
-
const title = obje?.get("TITL")?.toValue() ?? "";
|
|
5169
|
-
const type = obje
|
|
5170
|
-
|
|
5171
|
-
|
|
5285
|
+
const title = obje?.get("FILE.TITL")?.toValue() ?? obje?.get("TITL")?.toValue() ?? "";
|
|
5286
|
+
const type = resolveObjeForm(obje) ?? (url ? getFileExtension(url) : void 0) ?? "raw";
|
|
5287
|
+
let imgId = clone || mser;
|
|
5288
|
+
const hasEmbeddedOrLocalFile = !!url && (url.startsWith("data:") || url.startsWith("blob:") || !/^https?:\/\//i.test(url));
|
|
5289
|
+
if (!hasEmbeddedOrLocalFile && (!www || !tree || !this.id)) {
|
|
5290
|
+
return;
|
|
5291
|
+
}
|
|
5292
|
+
if (!this.id) {
|
|
5172
5293
|
return;
|
|
5173
5294
|
}
|
|
5174
5295
|
if (!namespace && !url) {
|
|
@@ -5186,13 +5307,16 @@ var Indi = class extends Common {
|
|
|
5186
5307
|
}
|
|
5187
5308
|
url = url || `https://${www}/mediaui-viewer/tree/${tree}/media/${media}`;
|
|
5188
5309
|
}
|
|
5310
|
+
if (!imgId && hasEmbeddedOrLocalFile && url) {
|
|
5311
|
+
imgId = typeof media === "string" && media || `local-${String(key).replace(/[@]/g, "")}-${getFileExtension(url) || "bin"}`;
|
|
5312
|
+
}
|
|
5189
5313
|
if (url && imgId) {
|
|
5190
|
-
const id = `${tree}-${this.id}-${imgId}`;
|
|
5314
|
+
const id = `${tree || "gedzip"}-${this.id}-${imgId}`;
|
|
5191
5315
|
list[id] = {
|
|
5192
5316
|
key,
|
|
5193
5317
|
isPrimary,
|
|
5194
5318
|
id,
|
|
5195
|
-
tree,
|
|
5319
|
+
tree: tree || "gedzip",
|
|
5196
5320
|
imgId,
|
|
5197
5321
|
person: this.id,
|
|
5198
5322
|
title,
|
|
@@ -5238,9 +5362,11 @@ var Indi = class extends Common {
|
|
|
5238
5362
|
obje.standardizeMedia();
|
|
5239
5363
|
const isPrimary = obje?.get("_PRIM")?.toValue() === "Y";
|
|
5240
5364
|
const url = obje?.get("FILE")?.toValue();
|
|
5241
|
-
const title = obje?.get("NOTE")?.toValue() ?? "";
|
|
5242
|
-
const type = obje
|
|
5243
|
-
const
|
|
5365
|
+
const title = obje?.get("FILE.NOTE")?.toValue() ?? obje?.get("NOTE")?.toValue() ?? "";
|
|
5366
|
+
const type = resolveObjeForm(obje) ?? (url ? getFileExtension(url) : void 0) ?? "raw";
|
|
5367
|
+
const photoRin = obje?.get("_PHOTO_RIN")?.toValue();
|
|
5368
|
+
const hasEmbeddedOrLocalFile = !!url && (url.startsWith("data:") || url.startsWith("blob:") || !/^https?:\/\//i.test(url));
|
|
5369
|
+
const imgId = photoRin || (hasEmbeddedOrLocalFile && url ? `local-${String(key).replace(/[@]/g, "")}-${getFileExtension(url) || "bin"}` : void 0);
|
|
5244
5370
|
if (url && imgId) {
|
|
5245
5371
|
const id = `${tree}-${this.id}-${imgId}`;
|
|
5246
5372
|
list[id] = {
|
|
@@ -5363,10 +5489,10 @@ var Indi = class extends Common {
|
|
|
5363
5489
|
const isPrimary = obje?.get("_PRIM")?.toValue() === "Y";
|
|
5364
5490
|
const url = obje?.get("FILE")?.toValue();
|
|
5365
5491
|
const title = obje?.get("TITL")?.toValue() ?? "";
|
|
5366
|
-
const type = obje
|
|
5492
|
+
const type = resolveObjeForm(obje) ?? (url ? getFileExtension(url) : void 0) ?? "raw";
|
|
5367
5493
|
if (url) {
|
|
5368
5494
|
const urlMatch = url.match(/\/([^/]+)\?hash=/);
|
|
5369
|
-
const imgId = urlMatch?.[1] || `img-${index}-${Date.now().toString(36)}
|
|
5495
|
+
const imgId = urlMatch?.[1] || (url.startsWith("data:") ? `data-${index}-${getFileExtension(url) || "bin"}` : `img-${index}-${Date.now().toString(36)}`);
|
|
5370
5496
|
const id = `geni-${geniId}-${imgId}`;
|
|
5371
5497
|
list[id] = {
|
|
5372
5498
|
isPrimary,
|
|
@@ -5403,10 +5529,10 @@ var Indi = class extends Common {
|
|
|
5403
5529
|
obje.standardizeMedia();
|
|
5404
5530
|
const isPrimary = obje?.get("_PRIM")?.toValue() === "Y";
|
|
5405
5531
|
const url = obje?.get("FILE")?.toValue();
|
|
5406
|
-
const title = obje?.get("TITL")?.toValue() ?? "";
|
|
5407
|
-
const type = obje
|
|
5532
|
+
const title = obje?.get("FILE.TITL")?.toValue() ?? obje?.get("TITL")?.toValue() ?? "";
|
|
5533
|
+
const type = resolveObjeForm(obje) ?? (url ? getFileExtension(url) : void 0) ?? "raw";
|
|
5408
5534
|
if (url) {
|
|
5409
|
-
const imgId = `media-${index}-${url.split("/").pop()?.split("?")[0]?.substring(0, 20) || Date.now().toString(36)}`;
|
|
5535
|
+
const imgId = `media-${index}-${url.startsWith("data:") ? getFileExtension(url) || "bin" : url.split("/").pop()?.split("?")[0]?.substring(0, 20) || Date.now().toString(36)}`;
|
|
5410
5536
|
const id = `${treeId}-${this.id}-${imgId}`;
|
|
5411
5537
|
list[id] = {
|
|
5412
5538
|
isPrimary,
|
|
@@ -5446,7 +5572,20 @@ var Indi = class extends Common {
|
|
|
5446
5572
|
cacheKey
|
|
5447
5573
|
);
|
|
5448
5574
|
if (cached !== void 0) {
|
|
5449
|
-
|
|
5575
|
+
if (cached?.file && !isRemoteOrEmbeddedMediaUrl(cached.file)) {
|
|
5576
|
+
const resolvedCached = await resolveLocalMediaUrl(cached.file);
|
|
5577
|
+
if (resolvedCached && isRemoteOrEmbeddedMediaUrl(resolvedCached)) {
|
|
5578
|
+
const refreshed = { ...cached, file: resolvedCached };
|
|
5579
|
+
profilePictureCache(
|
|
5580
|
+
this._gedcom,
|
|
5581
|
+
cacheKey,
|
|
5582
|
+
refreshed
|
|
5583
|
+
);
|
|
5584
|
+
return refreshed;
|
|
5585
|
+
}
|
|
5586
|
+
} else {
|
|
5587
|
+
return cached;
|
|
5588
|
+
}
|
|
5450
5589
|
}
|
|
5451
5590
|
const mediaList = await this.multimedia(namespace);
|
|
5452
5591
|
if (!mediaList) {
|
|
@@ -5458,39 +5597,40 @@ var Indi = class extends Common {
|
|
|
5458
5597
|
return void 0;
|
|
5459
5598
|
}
|
|
5460
5599
|
const mediaArray = Object.values(mediaList);
|
|
5461
|
-
const
|
|
5462
|
-
|
|
5463
|
-
|
|
5464
|
-
|
|
5465
|
-
|
|
5466
|
-
|
|
5467
|
-
|
|
5468
|
-
|
|
5469
|
-
|
|
5600
|
+
const toDisplayableProfile = async (media, isPrimary) => {
|
|
5601
|
+
const resolvedFile = await resolveLocalMediaUrl(media.url);
|
|
5602
|
+
if (!resolvedFile || !isRemoteOrEmbeddedMediaUrl(resolvedFile)) {
|
|
5603
|
+
return void 0;
|
|
5604
|
+
}
|
|
5605
|
+
return {
|
|
5606
|
+
file: resolvedFile,
|
|
5607
|
+
form: media.contentType,
|
|
5608
|
+
title: media.title,
|
|
5609
|
+
isPrimary
|
|
5470
5610
|
};
|
|
5471
|
-
|
|
5472
|
-
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
|
|
5476
|
-
this._gedcom,
|
|
5477
|
-
cacheKey,
|
|
5478
|
-
void 0
|
|
5479
|
-
);
|
|
5480
|
-
return void 0;
|
|
5481
|
-
}
|
|
5482
|
-
const secondaryMedia = mediaArray.find(
|
|
5483
|
-
(media) => isImageFormat(media.contentType || getFileExtension(media.url))
|
|
5611
|
+
};
|
|
5612
|
+
const candidates = mediaArray.filter(
|
|
5613
|
+
(media) => isImageFormat(
|
|
5614
|
+
media.contentType || media.url || getFileExtension(media.url)
|
|
5615
|
+
)
|
|
5484
5616
|
);
|
|
5485
|
-
|
|
5486
|
-
|
|
5487
|
-
|
|
5488
|
-
|
|
5489
|
-
|
|
5490
|
-
|
|
5491
|
-
|
|
5492
|
-
|
|
5493
|
-
|
|
5617
|
+
const ordered = [
|
|
5618
|
+
...candidates.filter((media) => media.isPrimary),
|
|
5619
|
+
...candidates.filter((media) => !media.isPrimary)
|
|
5620
|
+
];
|
|
5621
|
+
for (const media of ordered) {
|
|
5622
|
+
if (onlyPrimary && !media.isPrimary) {
|
|
5623
|
+
break;
|
|
5624
|
+
}
|
|
5625
|
+
const result = await toDisplayableProfile(media, !!media.isPrimary);
|
|
5626
|
+
if (result) {
|
|
5627
|
+
profilePictureCache(
|
|
5628
|
+
this._gedcom,
|
|
5629
|
+
cacheKey,
|
|
5630
|
+
result
|
|
5631
|
+
);
|
|
5632
|
+
return result;
|
|
5633
|
+
}
|
|
5494
5634
|
}
|
|
5495
5635
|
profilePictureCache(
|
|
5496
5636
|
this._gedcom,
|
|
@@ -5776,9 +5916,108 @@ var Indi = class extends Common {
|
|
|
5776
5916
|
addParent(parent, pedigree) {
|
|
5777
5917
|
return parent.addChild(this, pedigree);
|
|
5778
5918
|
}
|
|
5919
|
+
/**
|
|
5920
|
+
* Link an existing top-level OBJE record to this individual (`1 OBJE @On@`).
|
|
5921
|
+
*/
|
|
5922
|
+
attachMultimedia(objeOrKey, options) {
|
|
5923
|
+
if (!this._gedcom || !this.id) {
|
|
5924
|
+
return void 0;
|
|
5925
|
+
}
|
|
5926
|
+
const obje = typeof objeOrKey === "string" ? this._gedcom.obje(objeOrKey) : objeOrKey;
|
|
5927
|
+
if (!obje?.id) {
|
|
5928
|
+
return void 0;
|
|
5929
|
+
}
|
|
5930
|
+
const already = this.get("OBJE")?.toList()?.values()?.some((item) => item?.toValue?.() === obje.id);
|
|
5931
|
+
if (!already) {
|
|
5932
|
+
const pointer = makePointer(
|
|
5933
|
+
this._gedcom,
|
|
5934
|
+
this,
|
|
5935
|
+
obje.id,
|
|
5936
|
+
"OBJE"
|
|
5937
|
+
);
|
|
5938
|
+
this.assign("OBJE", pointer);
|
|
5939
|
+
}
|
|
5940
|
+
if (options?.primary) {
|
|
5941
|
+
this.get("OBJE")?.toList()?.forEach((item) => {
|
|
5942
|
+
const target = item?.refType === "OBJE" ? this._gedcom?.obje(
|
|
5943
|
+
String(item.toValue())
|
|
5944
|
+
) : item;
|
|
5945
|
+
if (!target) {
|
|
5946
|
+
return;
|
|
5947
|
+
}
|
|
5948
|
+
if (target.id === obje.id) {
|
|
5949
|
+
target.set("_PRIM", "Y");
|
|
5950
|
+
} else if (target.get("_PRIM")?.toValue() === "Y") {
|
|
5951
|
+
target.set("_PRIM", "N");
|
|
5952
|
+
}
|
|
5953
|
+
});
|
|
5954
|
+
obje.set("_PRIM", "Y");
|
|
5955
|
+
}
|
|
5956
|
+
return obje;
|
|
5957
|
+
}
|
|
5958
|
+
detachMultimedia(objeKey) {
|
|
5959
|
+
const list = this.get("OBJE")?.toList();
|
|
5960
|
+
if (!list) {
|
|
5961
|
+
return;
|
|
5962
|
+
}
|
|
5963
|
+
const toRemove = list.values().filter(
|
|
5964
|
+
(item) => item?.toValue?.() === objeKey || item?.id === objeKey
|
|
5965
|
+
);
|
|
5966
|
+
toRemove.forEach((item) => {
|
|
5967
|
+
if (item) {
|
|
5968
|
+
list.delete(item);
|
|
5969
|
+
}
|
|
5970
|
+
});
|
|
5971
|
+
if (list.length === 0) {
|
|
5972
|
+
this.remove("OBJE");
|
|
5973
|
+
}
|
|
5974
|
+
}
|
|
5975
|
+
/**
|
|
5976
|
+
* Create a multimedia record and attach it to this person.
|
|
5977
|
+
*/
|
|
5978
|
+
attachMediaFromUrl(url, options) {
|
|
5979
|
+
if (!this._gedcom || !url) {
|
|
5980
|
+
return void 0;
|
|
5981
|
+
}
|
|
5982
|
+
const obje = this._gedcom.createMultimediaRecord({
|
|
5983
|
+
file: url,
|
|
5984
|
+
form: options?.form,
|
|
5985
|
+
title: options?.title,
|
|
5986
|
+
mediType: options?.mediType,
|
|
5987
|
+
primary: options?.primary,
|
|
5988
|
+
gedcomVersion: options?.gedcomVersion
|
|
5989
|
+
});
|
|
5990
|
+
return this.attachMultimedia(obje, { primary: options?.primary });
|
|
5991
|
+
}
|
|
5992
|
+
/**
|
|
5993
|
+
* Link a shared SNOTE record via `1 NOTE @Nn@` (GEDCOM 7).
|
|
5994
|
+
*/
|
|
5995
|
+
attachSharedNote(noteOrKey) {
|
|
5996
|
+
if (!this._gedcom || !this.id) {
|
|
5997
|
+
return void 0;
|
|
5998
|
+
}
|
|
5999
|
+
const note = typeof noteOrKey === "string" ? this._gedcom.snote(noteOrKey) : noteOrKey;
|
|
6000
|
+
if (!note?.id) {
|
|
6001
|
+
return void 0;
|
|
6002
|
+
}
|
|
6003
|
+
const already = this.get("NOTE")?.toList()?.values()?.some((item) => item?.toValue?.() === note.id);
|
|
6004
|
+
if (!already) {
|
|
6005
|
+
const pointer = makePointer(
|
|
6006
|
+
this._gedcom,
|
|
6007
|
+
this,
|
|
6008
|
+
note.id,
|
|
6009
|
+
"SNOTE"
|
|
6010
|
+
);
|
|
6011
|
+
this.assign("NOTE", pointer);
|
|
6012
|
+
}
|
|
6013
|
+
return note;
|
|
6014
|
+
}
|
|
5779
6015
|
addFact(input) {
|
|
5780
6016
|
return addIndividualFact(this, input);
|
|
5781
6017
|
}
|
|
6018
|
+
addNonEvent(input) {
|
|
6019
|
+
return addNonEvent(this, input);
|
|
6020
|
+
}
|
|
5782
6021
|
getParentType(id) {
|
|
5783
6022
|
let indi;
|
|
5784
6023
|
if (typeof id === "string" || typeof id === "number") {
|
|
@@ -5819,7 +6058,7 @@ var Indi = class extends Common {
|
|
|
5819
6058
|
if (!famChild) {
|
|
5820
6059
|
const childIndi = this._gedcom?.indi(child.id);
|
|
5821
6060
|
const childState = childIndi?.get("FAMC")?.toList()?.filter((item) => item.value === family.id).index(0);
|
|
5822
|
-
childType = childState?.get("PEDI")?.toValue() || "biological" /* BIOLOGICAL */;
|
|
6061
|
+
childType = (childState?.get("PEDI") ?? childState?.get("PEDT"))?.toValue() || "biological" /* BIOLOGICAL */;
|
|
5823
6062
|
} else {
|
|
5824
6063
|
childType = famChild.get(usedRel)?.toValue() || "biological" /* BIOLOGICAL */;
|
|
5825
6064
|
}
|
|
@@ -6380,7 +6619,7 @@ var Indi = class extends Common {
|
|
|
6380
6619
|
return;
|
|
6381
6620
|
}
|
|
6382
6621
|
const childState = child?.get("FAMC")?.toList()?.filter((item) => item.value === family.id).index(0);
|
|
6383
|
-
const childType = childState?.get("PEDI")?.toValue() || "biological" /* BIOLOGICAL */;
|
|
6622
|
+
const childType = (childState?.get("PEDI") ?? childState?.get("PEDT"))?.toValue() || "biological" /* BIOLOGICAL */;
|
|
6384
6623
|
if (childType?.toLowerCase() === filter.PEDI.toLowerCase()) {
|
|
6385
6624
|
children.append(child);
|
|
6386
6625
|
}
|
|
@@ -6488,7 +6727,7 @@ var Indi = class extends Common {
|
|
|
6488
6727
|
const child = this.id && family.CHIL?.toValueList()?.item(this.id);
|
|
6489
6728
|
if (!child) {
|
|
6490
6729
|
const childState = this?.get("FAMC")?.toList()?.filter((item) => item.value === family.id).index(0);
|
|
6491
|
-
const parentType = childState?.get("PEDI")?.toValue() || "biological" /* BIOLOGICAL */;
|
|
6730
|
+
const parentType = (childState?.get("PEDI") ?? childState?.get("PEDT"))?.toValue() || "biological" /* BIOLOGICAL */;
|
|
6492
6731
|
if (parentType?.toLowerCase() === filter.PEDI.toLowerCase()) {
|
|
6493
6732
|
parents.merge(family.getParents());
|
|
6494
6733
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gedcom.d.ts","sourceRoot":"","sources":["../../src/structures/gedcom.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAE3D,OAAO,KAAK,iBAAiB,MAAM,WAAW,CAAC;AAC/C,OAAO,KAAK,cAAc,MAAM,QAAQ,CAAC;AAEzC,UAAU,gBACT,SACC,MAAM,EACN,IAAI,CAAC,WAAW,EAAE,IAAI,GAAG,OAAO,CAAC,EACjC,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,EAAE,EAAE,IAAI,CAAC,CAAC;IACpC,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,OAAO,CAAC,EAAE,QAAQ,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,UAAU,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,GAAG;QACf,IAAI,CAAC,EAAE,MAAM,GAAG;YACf,IAAI,CAAC,EAAE,MAAM,CAAC;SACd,CAAC;QACF,KAAK,CAAC,EAAE,MAAM,GAAG;YAChB,GAAG,CAAC,EAAE,MAAM,CAAC;SACb,CAAC;QACF,IAAI,CAAC,EAAE,MAAM,GAAG;YACf,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,IAAI,CAAC,EAAE,MAAM,GAAG;gBACf,IAAI,CAAC,EAAE,MAAM,CAAC;gBACd,KAAK,CAAC,EAAE,MAAM,CAAC;gBACf,GAAG,CAAC,EAAE,MAAM,CAAC;gBACb,GAAG,CAAC,EAAE,MAAM,CAAC;aACb,GAAG,iBAAiB,CAAC;YACtB,IAAI,CAAC,EAAE,MAAM,GAAG;gBACf,IAAI,CAAC,EAAE,MAAM,GAAG;oBACf,IAAI,CAAC,EAAE,MAAM,CAAC;iBACd,CAAC;gBACF,IAAI,CAAC,EAAE,MAAM,CAAC;aACd,CAAC;YACF,KAAK,CAAC,EAAE,MAAM,GAAG;gBAChB,GAAG,CAAC,EAAE,MAAM,CAAC;aACb,CAAC;SACF,CAAC;QAEF,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,GAAG;YACf,IAAI,CAAC,EAAE,MAAM,CAAC;SACd,CAAC;QACF,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,GAAG;YACf,IAAI,CAAC,EAAE,MAAM,CAAC;SACd,CAAC;KACF,GAAG,cAAc,CAAC;CACnB;AACD,eAAe,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"gedcom.d.ts","sourceRoot":"","sources":["../../src/structures/gedcom.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAE3D,OAAO,KAAK,iBAAiB,MAAM,WAAW,CAAC;AAC/C,OAAO,KAAK,cAAc,MAAM,QAAQ,CAAC;AAEzC,UAAU,gBACT,SACC,MAAM,EACN,IAAI,CAAC,WAAW,EAAE,IAAI,GAAG,OAAO,CAAC,EACjC,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,EAAE,EAAE,IAAI,CAAC,CAAC;IACpC,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,OAAO,CAAC,EAAE,QAAQ,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,UAAU,CAAC;IACtB,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,GAAG;QACf,IAAI,CAAC,EAAE,MAAM,GAAG;YACf,IAAI,CAAC,EAAE,MAAM,CAAC;SACd,CAAC;QACF,KAAK,CAAC,EAAE,MAAM,GAAG;YAChB,GAAG,CAAC,EAAE,MAAM,CAAC;SACb,CAAC;QACF,IAAI,CAAC,EAAE,MAAM,GAAG;YACf,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,IAAI,CAAC,EAAE,MAAM,GAAG;gBACf,IAAI,CAAC,EAAE,MAAM,CAAC;gBACd,KAAK,CAAC,EAAE,MAAM,CAAC;gBACf,GAAG,CAAC,EAAE,MAAM,CAAC;gBACb,GAAG,CAAC,EAAE,MAAM,CAAC;aACb,GAAG,iBAAiB,CAAC;YACtB,IAAI,CAAC,EAAE,MAAM,GAAG;gBACf,IAAI,CAAC,EAAE,MAAM,GAAG;oBACf,IAAI,CAAC,EAAE,MAAM,CAAC;iBACd,CAAC;gBACF,IAAI,CAAC,EAAE,MAAM,CAAC;aACd,CAAC;YACF,KAAK,CAAC,EAAE,MAAM,GAAG;gBAChB,GAAG,CAAC,EAAE,MAAM,CAAC;aACb,CAAC;SACF,CAAC;QAEF,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,GAAG;YACf,IAAI,CAAC,EAAE,MAAM,CAAC;SACd,CAAC;QACF,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,GAAG;YACf,IAAI,CAAC,EAAE,MAAM,CAAC;SACd,CAAC;KACF,GAAG,cAAc,CAAC;CACnB;AACD,eAAe,gBAAgB,CAAC"}
|