@treeviz/gedcom-parser 2.1.9 → 2.1.11

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/dist/cli/index.js CHANGED
@@ -41,6 +41,82 @@ var appendGedcomTrailer = (serialized) => {
41
41
  }
42
42
  return `${trimmed}${newline}0 TRLR`;
43
43
  };
44
+
45
+ // src/utils/media-utils.ts
46
+ var getFileExtension = (filename) => {
47
+ if (!filename) {
48
+ return "";
49
+ }
50
+ if (filename.startsWith("data:")) {
51
+ const mime = filename.slice(5).split(";")[0] || "";
52
+ const subtype = (mime.split("/")[1] || "").toLowerCase();
53
+ if (subtype === "jpeg") {
54
+ return "jpg";
55
+ }
56
+ return subtype.split("+")[0] || "";
57
+ }
58
+ const withoutQuery = filename.split(/[?#]/)[0] || filename;
59
+ const match = withoutQuery.match(/\.([^.]+)$/);
60
+ return match ? match[1].toLowerCase() : "";
61
+ };
62
+ var isImageFormat = (format2) => {
63
+ if (!format2) {
64
+ return false;
65
+ }
66
+ let normalized = format2.toLowerCase().trim();
67
+ if (normalized.startsWith("data:")) {
68
+ normalized = getFileExtension(normalized);
69
+ } else if (normalized.includes("/")) {
70
+ normalized = normalized.split("/")[1]?.split("+")[0] || "";
71
+ if (normalized === "jpeg") {
72
+ normalized = "jpg";
73
+ }
74
+ }
75
+ const imageFormats = [
76
+ "jpg",
77
+ "jpeg",
78
+ "png",
79
+ "gif",
80
+ "bmp",
81
+ "webp",
82
+ "svg",
83
+ "tiff",
84
+ "tif"
85
+ ];
86
+ return imageFormats.includes(normalized);
87
+ };
88
+ var resolveObjeForm = (obje) => {
89
+ const value = obje?.get?.("FILE.FORM")?.toValue?.() ?? obje?.get?.("FORM")?.toValue?.();
90
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
91
+ };
92
+ var mediaIdValue = (obje, path) => {
93
+ const value = obje?.get?.(path)?.toValue?.();
94
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
95
+ };
96
+ var resolveObjeMediaId = (obje) => mediaIdValue(obje, "RIN") || mediaIdValue(obje, "_CLON._OID") || mediaIdValue(obje, "_MSER._LKID") || mediaIdValue(obje, "_OID") || mediaIdValue(obje, "_LKID");
97
+ var ANCESTRY_MEDIA_RETRIEVAL_PREFIX = "https://www.ancestry.com/api/media/retrieval/v2/image";
98
+ var ANCESTRY_MEDIA_QUERY = "client=trees-mediaservice&imageQuality=hq";
99
+ var ancestryMediaPath = (namespace, imgId) => `/namespaces/${namespace}/media/${imgId}?${ANCESTRY_MEDIA_QUERY}`;
100
+ var ancestryMediaFileUrl = (namespace, imgId) => {
101
+ if (!namespace || !imgId) {
102
+ return void 0;
103
+ }
104
+ return `${ANCESTRY_MEDIA_RETRIEVAL_PREFIX}${ancestryMediaPath(namespace, imgId)}`;
105
+ };
106
+ var objeXrefKey = (obje, fallback = 0) => {
107
+ if (typeof obje?.id === "string" && obje.id) {
108
+ return obje.id;
109
+ }
110
+ const value = obje?.toValue?.();
111
+ if (typeof value === "string" && value.trim()) {
112
+ return value.trim();
113
+ }
114
+ if (typeof fallback === "string" && fallback.trim()) {
115
+ return fallback.trim();
116
+ }
117
+ return `@O${fallback}@`;
118
+ };
119
+ var objeNoteValue = (obje) => mediaIdValue(obje, "FILE.NOTE") || mediaIdValue(obje, "NOTE") || "";
44
120
  var List = class _List {
45
121
  // length = 0;
46
122
  constructor(items) {
@@ -690,7 +766,7 @@ var Common = class _Common {
690
766
  this,
691
767
  options.obje.namespace,
692
768
  options.obje.override,
693
- void 0,
769
+ this.isAncestry() ? ancestryMediaFileUrl : void 0,
694
770
  options.gedcomVersion
695
771
  );
696
772
  }
@@ -1209,11 +1285,8 @@ var storeCache = {
1209
1285
  getCacheDbs().relativesOnDegreeCache.setItem(value);
1210
1286
  }
1211
1287
  }, 50),
1212
- // profilePictureCache IS persisted to IndexedDB
1288
+ // Image bytes are stored as one IndexedDB record per photo.
1213
1289
  profilePictureCache: debounce((value) => {
1214
- if (value) {
1215
- getCacheDbs().profilePictureCache.setItem(value);
1216
- }
1217
1290
  }, 100)
1218
1291
  };
1219
1292
  var resetRelativesCache = () => {
@@ -2269,65 +2342,23 @@ var isRemoteOrEmbeddedMediaUrl = (path) => {
2269
2342
  }
2270
2343
  return path.startsWith("data:") || path.startsWith("blob:") || /^https?:\/\//i.test(path);
2271
2344
  };
2272
- var resolveLocalMediaUrl = async (path) => {
2345
+ var resolveLocalMediaUrl = async (path, context) => {
2273
2346
  if (!path) {
2274
2347
  return void 0;
2275
2348
  }
2276
- if (isRemoteOrEmbeddedMediaUrl(path)) {
2349
+ if (path.startsWith("data:") || path.startsWith("blob:")) {
2277
2350
  return path;
2278
2351
  }
2279
- const resolved = await localMediaResolver?.(path);
2280
- return resolved;
2281
- };
2282
- var implemented = (type, ...args) => {
2283
- };
2284
-
2285
- // src/utils/media-utils.ts
2286
- var getFileExtension = (filename) => {
2287
- if (!filename) {
2288
- return "";
2289
- }
2290
- if (filename.startsWith("data:")) {
2291
- const mime = filename.slice(5).split(";")[0] || "";
2292
- const subtype = (mime.split("/")[1] || "").toLowerCase();
2293
- if (subtype === "jpeg") {
2294
- return "jpg";
2295
- }
2296
- return subtype.split("+")[0] || "";
2352
+ const resolved = await localMediaResolver?.(path, context);
2353
+ if (resolved) {
2354
+ return resolved;
2297
2355
  }
2298
- const withoutQuery = filename.split(/[?#]/)[0] || filename;
2299
- const match = withoutQuery.match(/\.([^.]+)$/);
2300
- return match ? match[1].toLowerCase() : "";
2301
- };
2302
- var isImageFormat = (format2) => {
2303
- if (!format2) {
2304
- return false;
2305
- }
2306
- let normalized = format2.toLowerCase().trim();
2307
- if (normalized.startsWith("data:")) {
2308
- normalized = getFileExtension(normalized);
2309
- } else if (normalized.includes("/")) {
2310
- normalized = normalized.split("/")[1]?.split("+")[0] || "";
2311
- if (normalized === "jpeg") {
2312
- normalized = "jpg";
2313
- }
2356
+ if (/^https?:\/\//i.test(path)) {
2357
+ return path;
2314
2358
  }
2315
- const imageFormats = [
2316
- "jpg",
2317
- "jpeg",
2318
- "png",
2319
- "gif",
2320
- "bmp",
2321
- "webp",
2322
- "svg",
2323
- "tiff",
2324
- "tif"
2325
- ];
2326
- return imageFormats.includes(normalized);
2359
+ return void 0;
2327
2360
  };
2328
- var resolveObjeForm = (obje) => {
2329
- const value = obje?.get?.("FILE.FORM")?.toValue?.() ?? obje?.get?.("FORM")?.toValue?.();
2330
- return typeof value === "string" && value.trim() ? value.trim() : void 0;
2361
+ var implemented = (type, ...args) => {
2331
2362
  };
2332
2363
  var uniqueItemsCache = /* @__PURE__ */ new WeakMap();
2333
2364
  var setNestedGroup = (obj, key, value, uniqueCounting = true) => {
@@ -3504,22 +3535,19 @@ var Indi = class extends Common {
3504
3535
  if (objeList) {
3505
3536
  await Promise.all(
3506
3537
  objeList.map(async (objeRef) => {
3507
- const key = objeRef?.id;
3538
+ const key = objeXrefKey(objeRef, 0);
3508
3539
  const obje = objeRef?.standardizeMedia(
3509
3540
  namespace,
3510
3541
  true,
3511
- (ns, iId) => {
3512
- return ns && iId ? `https://mediasvc.ancestry.com/v2/image/namespaces/${ns}/media/${iId}?client=trees-mediaservice&imageQuality=hq` : void 0;
3513
- }
3542
+ ancestryMediaFileUrl
3514
3543
  );
3515
3544
  const isPrimary = obje?.get("_PRIM")?.toValue() === "Y";
3516
- const media = obje?.RIN?.toValue() || obje?.get("_OID")?.toValue();
3517
- const clone = obje?.get("_CLON._OID")?.toValue();
3518
- const mser = obje?.get("_MSER._LKID")?.toValue();
3545
+ const media = resolveObjeMediaId(obje);
3519
3546
  let url = obje?.get("FILE")?.toValue();
3520
3547
  const title = obje?.get("FILE.TITL")?.toValue() ?? obje?.get("TITL")?.toValue() ?? "";
3548
+ const note = objeNoteValue(obje);
3521
3549
  const type = resolveObjeForm(obje) ?? (url ? getFileExtension(url) : void 0) ?? "raw";
3522
- let imgId = clone || mser;
3550
+ let imgId = media;
3523
3551
  const hasEmbeddedOrLocalFile = !!url && (url.startsWith("data:") || url.startsWith("blob:") || !/^https?:\/\//i.test(url));
3524
3552
  if (!hasEmbeddedOrLocalFile && (!www || !tree || !this.id)) {
3525
3553
  return;
@@ -3555,6 +3583,7 @@ var Indi = class extends Common {
3555
3583
  imgId,
3556
3584
  person: this.id,
3557
3585
  title,
3586
+ note,
3558
3587
  url,
3559
3588
  contentType: type,
3560
3589
  downloadName: `${this.id.replaceAll("@", "")}_${this.toNaturalName()?.replaceAll(" ", "-") || ""}_${(title || key.replaceAll("@", "").toString()).replaceAll(" ", "-")}`
@@ -3593,7 +3622,7 @@ var Indi = class extends Common {
3593
3622
  return;
3594
3623
  }
3595
3624
  const obje = o;
3596
- const key = `@O${index}@`;
3625
+ const key = objeXrefKey(obje, index);
3597
3626
  obje.standardizeMedia();
3598
3627
  const isPrimary = obje?.get("_PRIM")?.toValue() === "Y";
3599
3628
  const url = obje?.get("FILE")?.toValue();
@@ -3612,6 +3641,7 @@ var Indi = class extends Common {
3612
3641
  imgId,
3613
3642
  person: this.id,
3614
3643
  title,
3644
+ note: objeNoteValue(obje),
3615
3645
  url,
3616
3646
  contentType: type,
3617
3647
  downloadName: `${this.id.replaceAll("@", "")}_${this.toNaturalName()?.replaceAll(" ", "-") || ""}_${(title || key.replaceAll("@", "").toString()).replaceAll(" ", "-")}`
@@ -3720,7 +3750,7 @@ var Indi = class extends Common {
3720
3750
  if (!obje) {
3721
3751
  return;
3722
3752
  }
3723
- const key = `@O${index}@`;
3753
+ const key = objeXrefKey(obje, index);
3724
3754
  const isPrimary = obje?.get("_PRIM")?.toValue() === "Y";
3725
3755
  const url = obje?.get("FILE")?.toValue();
3726
3756
  const title = obje?.get("TITL")?.toValue() ?? "";
@@ -3737,6 +3767,7 @@ var Indi = class extends Common {
3737
3767
  imgId,
3738
3768
  person: this.id,
3739
3769
  title,
3770
+ note: objeNoteValue(obje),
3740
3771
  url,
3741
3772
  contentType: type,
3742
3773
  downloadName: `${this.id.replaceAll("@", "")}_${this.toNaturalName()?.replaceAll(" ", "-") || ""}_${(title || key.replaceAll("@", "").toString()).replaceAll(" ", "-")}`
@@ -3760,7 +3791,7 @@ var Indi = class extends Common {
3760
3791
  if (!obje) {
3761
3792
  return;
3762
3793
  }
3763
- const key = `@O${index}@`;
3794
+ const key = objeXrefKey(obje, index);
3764
3795
  obje.standardizeMedia();
3765
3796
  const isPrimary = obje?.get("_PRIM")?.toValue() === "Y";
3766
3797
  const url = obje?.get("FILE")?.toValue();
@@ -3777,6 +3808,7 @@ var Indi = class extends Common {
3777
3808
  imgId,
3778
3809
  person: this.id,
3779
3810
  title,
3811
+ note: objeNoteValue(obje),
3780
3812
  url,
3781
3813
  contentType: type,
3782
3814
  downloadName: `${this.id.replaceAll("@", "")}_${this.toNaturalName()?.replaceAll(" ", "-") || ""}_${(title || key.replaceAll("@", "").toString()).replaceAll(" ", "-")}`
@@ -3808,7 +3840,12 @@ var Indi = class extends Common {
3808
3840
  );
3809
3841
  if (cached !== void 0) {
3810
3842
  if (cached?.file && !isRemoteOrEmbeddedMediaUrl(cached.file)) {
3811
- const resolvedCached = await resolveLocalMediaUrl(cached.file);
3843
+ const resolvedCached = await resolveLocalMediaUrl(cached.file, {
3844
+ url: cached.file,
3845
+ person: this.id,
3846
+ tree: this.getTreeId?.(),
3847
+ treeName: this.getTreeName?.()
3848
+ });
3812
3849
  if (resolvedCached && isRemoteOrEmbeddedMediaUrl(resolvedCached)) {
3813
3850
  const refreshed = { ...cached, file: resolvedCached };
3814
3851
  profilePictureCache(
@@ -3833,7 +3870,16 @@ var Indi = class extends Common {
3833
3870
  }
3834
3871
  const mediaArray = Object.values(mediaList);
3835
3872
  const toDisplayableProfile = async (media, isPrimary) => {
3836
- const resolvedFile = await resolveLocalMediaUrl(media.url);
3873
+ const resolvedFile = await resolveLocalMediaUrl(media.url, {
3874
+ url: media.url,
3875
+ id: media.id,
3876
+ imgId: media.imgId,
3877
+ key: media.key,
3878
+ contentType: media.contentType,
3879
+ person: media.person || this.id,
3880
+ tree: media.tree || this.getTreeId?.(),
3881
+ treeName: this.getTreeName?.()
3882
+ });
3837
3883
  if (!resolvedFile || !isRemoteOrEmbeddedMediaUrl(resolvedFile)) {
3838
3884
  return void 0;
3839
3885
  }
@@ -8611,7 +8657,7 @@ var ensureExtensionSchema = (gedcom, extraTags) => {
8611
8657
 
8612
8658
  // package.json
8613
8659
  var package_default = {
8614
- version: "2.1.9"};
8660
+ version: "2.1.11"};
8615
8661
 
8616
8662
  // src/utils/get-product-details.ts
8617
8663
  var isDevelopment = () => {
@@ -8694,16 +8740,26 @@ var Obje = class extends Common {
8694
8740
  if (!this._gedcom) {
8695
8741
  return this;
8696
8742
  }
8743
+ if (typeof this.value === "string" && isId(this.value) && this.refType === "OBJE") {
8744
+ const resolved = this.ref;
8745
+ if (resolved && resolved !== this && typeof resolved.standardizeMedia === "function") {
8746
+ resolved.standardizeMedia(
8747
+ namespace,
8748
+ override,
8749
+ urlGetter,
8750
+ gedcomVersion
8751
+ );
8752
+ return this;
8753
+ }
8754
+ }
8697
8755
  const rin = this?.get("RIN")?.toValue();
8698
- const clone = this?.get("_CLON._OID")?.toValue();
8699
- const mser = this?.get("_MSER._LKID")?.toValue();
8700
8756
  const title = this?.get("FILE.TITL")?.toValue() ?? this?.get("TITL")?.toValue() ?? "";
8701
8757
  const note = this?.get("FILE.NOTE")?.toValue() ?? this?.get("NOTE")?.toValue() ?? "";
8702
8758
  const formRaw = this?.get("FILE.FORM")?.toValue() ?? this?.get("FORM")?.toValue();
8703
8759
  const mediType = this?.get("FILE.FORM.TYPE")?.toValue() ?? this?.get("FORM.TYPE")?.toValue() ?? this?.get("MEDI")?.toValue();
8704
8760
  const file = this?.get("FILE")?.toValue();
8705
- const imgId = rin || clone || mser;
8706
- const url = file || namespace && urlGetter?.(namespace, imgId);
8761
+ const imgId = resolveObjeMediaId(this);
8762
+ const url = file || this.isAncestry() && namespace && urlGetter?.(namespace, imgId);
8707
8763
  if (!url) {
8708
8764
  return this;
8709
8765
  }
@@ -9216,6 +9272,22 @@ var GedCom = class extends Common {
9216
9272
  obje(index) {
9217
9273
  return this.getMain(this.objes(), index);
9218
9274
  }
9275
+ /**
9276
+ * People who link a shared multimedia record (`1 OBJE @On@`), i.e. Ancestry
9277
+ * face tags / everyone the photo is attached to.
9278
+ */
9279
+ indisLinkingObje(objeKey) {
9280
+ const people = [];
9281
+ this.indis()?.forEach((indi) => {
9282
+ const linked = indi?.get("OBJE")?.toList()?.values()?.some(
9283
+ (item) => item?.toValue?.() === objeKey || item?.id === objeKey
9284
+ );
9285
+ if (linked && indi) {
9286
+ people.push(indi);
9287
+ }
9288
+ });
9289
+ return people;
9290
+ }
9219
9291
  sour(index) {
9220
9292
  return this.getMain(this.sours(), index);
9221
9293
  }
@@ -171,11 +171,8 @@ var storeCache = {
171
171
  getCacheDbs().relativesOnDegreeCache.setItem(value);
172
172
  }
173
173
  }, 50),
174
- // profilePictureCache IS persisted to IndexedDB
174
+ // Image bytes are stored as one IndexedDB record per photo.
175
175
  profilePictureCache: debounce((value) => {
176
- if (value) {
177
- getCacheDbs().profilePictureCache.setItem(value);
178
- }
179
176
  }, 100)
180
177
  };
181
178
  var resetRelativesCache = () => {
@@ -555,6 +552,82 @@ var dateFormatter = (indi, showMarriages = false, showDays = false, showPlaces =
555
552
  // src/utils/gedcom-trailer.ts
556
553
  var GEDCOM_TRAILER_TAG = "TRLR";
557
554
  var isGedcomTrailerTag = (tag) => tag === GEDCOM_TRAILER_TAG;
555
+
556
+ // src/utils/media-utils.ts
557
+ var getFileExtension = (filename) => {
558
+ if (!filename) {
559
+ return "";
560
+ }
561
+ if (filename.startsWith("data:")) {
562
+ const mime = filename.slice(5).split(";")[0] || "";
563
+ const subtype = (mime.split("/")[1] || "").toLowerCase();
564
+ if (subtype === "jpeg") {
565
+ return "jpg";
566
+ }
567
+ return subtype.split("+")[0] || "";
568
+ }
569
+ const withoutQuery = filename.split(/[?#]/)[0] || filename;
570
+ const match = withoutQuery.match(/\.([^.]+)$/);
571
+ return match ? match[1].toLowerCase() : "";
572
+ };
573
+ var isImageFormat = (format2) => {
574
+ if (!format2) {
575
+ return false;
576
+ }
577
+ let normalized = format2.toLowerCase().trim();
578
+ if (normalized.startsWith("data:")) {
579
+ normalized = getFileExtension(normalized);
580
+ } else if (normalized.includes("/")) {
581
+ normalized = normalized.split("/")[1]?.split("+")[0] || "";
582
+ if (normalized === "jpeg") {
583
+ normalized = "jpg";
584
+ }
585
+ }
586
+ const imageFormats = [
587
+ "jpg",
588
+ "jpeg",
589
+ "png",
590
+ "gif",
591
+ "bmp",
592
+ "webp",
593
+ "svg",
594
+ "tiff",
595
+ "tif"
596
+ ];
597
+ return imageFormats.includes(normalized);
598
+ };
599
+ var resolveObjeForm = (obje) => {
600
+ const value = obje?.get?.("FILE.FORM")?.toValue?.() ?? obje?.get?.("FORM")?.toValue?.();
601
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
602
+ };
603
+ var mediaIdValue = (obje, path) => {
604
+ const value = obje?.get?.(path)?.toValue?.();
605
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
606
+ };
607
+ var resolveObjeMediaId = (obje) => mediaIdValue(obje, "RIN") || mediaIdValue(obje, "_CLON._OID") || mediaIdValue(obje, "_MSER._LKID") || mediaIdValue(obje, "_OID") || mediaIdValue(obje, "_LKID");
608
+ var ANCESTRY_MEDIA_RETRIEVAL_PREFIX = "https://www.ancestry.com/api/media/retrieval/v2/image";
609
+ var ANCESTRY_MEDIA_QUERY = "client=trees-mediaservice&imageQuality=hq";
610
+ var ancestryMediaPath = (namespace, imgId) => `/namespaces/${namespace}/media/${imgId}?${ANCESTRY_MEDIA_QUERY}`;
611
+ var ancestryMediaFileUrl = (namespace, imgId) => {
612
+ if (!namespace || !imgId) {
613
+ return void 0;
614
+ }
615
+ return `${ANCESTRY_MEDIA_RETRIEVAL_PREFIX}${ancestryMediaPath(namespace, imgId)}`;
616
+ };
617
+ var objeXrefKey = (obje, fallback = 0) => {
618
+ if (typeof obje?.id === "string" && obje.id) {
619
+ return obje.id;
620
+ }
621
+ const value = obje?.toValue?.();
622
+ if (typeof value === "string" && value.trim()) {
623
+ return value.trim();
624
+ }
625
+ if (typeof fallback === "string" && fallback.trim()) {
626
+ return fallback.trim();
627
+ }
628
+ return `@O${fallback}@`;
629
+ };
630
+ var objeNoteValue = (obje) => mediaIdValue(obje, "FILE.NOTE") || mediaIdValue(obje, "NOTE") || "";
558
631
  var List = class _List {
559
632
  // length = 0;
560
633
  constructor(items) {
@@ -1204,7 +1277,7 @@ var Common = class _Common {
1204
1277
  this,
1205
1278
  options.obje.namespace,
1206
1279
  options.obje.override,
1207
- void 0,
1280
+ this.isAncestry() ? ancestryMediaFileUrl : void 0,
1208
1281
  options.gedcomVersion
1209
1282
  );
1210
1283
  }
@@ -2152,65 +2225,23 @@ var isRemoteOrEmbeddedMediaUrl = (path) => {
2152
2225
  }
2153
2226
  return path.startsWith("data:") || path.startsWith("blob:") || /^https?:\/\//i.test(path);
2154
2227
  };
2155
- var resolveLocalMediaUrl = async (path) => {
2228
+ var resolveLocalMediaUrl = async (path, context) => {
2156
2229
  if (!path) {
2157
2230
  return void 0;
2158
2231
  }
2159
- if (isRemoteOrEmbeddedMediaUrl(path)) {
2232
+ if (path.startsWith("data:") || path.startsWith("blob:")) {
2160
2233
  return path;
2161
2234
  }
2162
- const resolved = await localMediaResolver?.(path);
2163
- return resolved;
2164
- };
2165
- var implemented = (type, ...args) => {
2166
- };
2167
-
2168
- // src/utils/media-utils.ts
2169
- var getFileExtension = (filename) => {
2170
- if (!filename) {
2171
- return "";
2172
- }
2173
- if (filename.startsWith("data:")) {
2174
- const mime = filename.slice(5).split(";")[0] || "";
2175
- const subtype = (mime.split("/")[1] || "").toLowerCase();
2176
- if (subtype === "jpeg") {
2177
- return "jpg";
2178
- }
2179
- return subtype.split("+")[0] || "";
2180
- }
2181
- const withoutQuery = filename.split(/[?#]/)[0] || filename;
2182
- const match = withoutQuery.match(/\.([^.]+)$/);
2183
- return match ? match[1].toLowerCase() : "";
2184
- };
2185
- var isImageFormat = (format2) => {
2186
- if (!format2) {
2187
- return false;
2235
+ const resolved = await localMediaResolver?.(path, context);
2236
+ if (resolved) {
2237
+ return resolved;
2188
2238
  }
2189
- let normalized = format2.toLowerCase().trim();
2190
- if (normalized.startsWith("data:")) {
2191
- normalized = getFileExtension(normalized);
2192
- } else if (normalized.includes("/")) {
2193
- normalized = normalized.split("/")[1]?.split("+")[0] || "";
2194
- if (normalized === "jpeg") {
2195
- normalized = "jpg";
2196
- }
2239
+ if (/^https?:\/\//i.test(path)) {
2240
+ return path;
2197
2241
  }
2198
- const imageFormats = [
2199
- "jpg",
2200
- "jpeg",
2201
- "png",
2202
- "gif",
2203
- "bmp",
2204
- "webp",
2205
- "svg",
2206
- "tiff",
2207
- "tif"
2208
- ];
2209
- return imageFormats.includes(normalized);
2242
+ return void 0;
2210
2243
  };
2211
- var resolveObjeForm = (obje) => {
2212
- const value = obje?.get?.("FILE.FORM")?.toValue?.() ?? obje?.get?.("FORM")?.toValue?.();
2213
- return typeof value === "string" && value.trim() ? value.trim() : void 0;
2244
+ var implemented = (type, ...args) => {
2214
2245
  };
2215
2246
  var uniqueItemsCache = /* @__PURE__ */ new WeakMap();
2216
2247
  var setNestedGroup = (obj, key, value, uniqueCounting = true) => {
@@ -3488,22 +3519,19 @@ var Indi = class extends Common {
3488
3519
  if (objeList) {
3489
3520
  await Promise.all(
3490
3521
  objeList.map(async (objeRef) => {
3491
- const key = objeRef?.id;
3522
+ const key = objeXrefKey(objeRef, 0);
3492
3523
  const obje = objeRef?.standardizeMedia(
3493
3524
  namespace,
3494
3525
  true,
3495
- (ns, iId) => {
3496
- return ns && iId ? `https://mediasvc.ancestry.com/v2/image/namespaces/${ns}/media/${iId}?client=trees-mediaservice&imageQuality=hq` : void 0;
3497
- }
3526
+ ancestryMediaFileUrl
3498
3527
  );
3499
3528
  const isPrimary = obje?.get("_PRIM")?.toValue() === "Y";
3500
- const media = obje?.RIN?.toValue() || obje?.get("_OID")?.toValue();
3501
- const clone = obje?.get("_CLON._OID")?.toValue();
3502
- const mser = obje?.get("_MSER._LKID")?.toValue();
3529
+ const media = resolveObjeMediaId(obje);
3503
3530
  let url = obje?.get("FILE")?.toValue();
3504
3531
  const title = obje?.get("FILE.TITL")?.toValue() ?? obje?.get("TITL")?.toValue() ?? "";
3532
+ const note = objeNoteValue(obje);
3505
3533
  const type = resolveObjeForm(obje) ?? (url ? getFileExtension(url) : void 0) ?? "raw";
3506
- let imgId = clone || mser;
3534
+ let imgId = media;
3507
3535
  const hasEmbeddedOrLocalFile = !!url && (url.startsWith("data:") || url.startsWith("blob:") || !/^https?:\/\//i.test(url));
3508
3536
  if (!hasEmbeddedOrLocalFile && (!www || !tree || !this.id)) {
3509
3537
  return;
@@ -3539,6 +3567,7 @@ var Indi = class extends Common {
3539
3567
  imgId,
3540
3568
  person: this.id,
3541
3569
  title,
3570
+ note,
3542
3571
  url,
3543
3572
  contentType: type,
3544
3573
  downloadName: `${this.id.replaceAll("@", "")}_${this.toNaturalName()?.replaceAll(" ", "-") || ""}_${(title || key.replaceAll("@", "").toString()).replaceAll(" ", "-")}`
@@ -3577,7 +3606,7 @@ var Indi = class extends Common {
3577
3606
  return;
3578
3607
  }
3579
3608
  const obje = o;
3580
- const key = `@O${index}@`;
3609
+ const key = objeXrefKey(obje, index);
3581
3610
  obje.standardizeMedia();
3582
3611
  const isPrimary = obje?.get("_PRIM")?.toValue() === "Y";
3583
3612
  const url = obje?.get("FILE")?.toValue();
@@ -3596,6 +3625,7 @@ var Indi = class extends Common {
3596
3625
  imgId,
3597
3626
  person: this.id,
3598
3627
  title,
3628
+ note: objeNoteValue(obje),
3599
3629
  url,
3600
3630
  contentType: type,
3601
3631
  downloadName: `${this.id.replaceAll("@", "")}_${this.toNaturalName()?.replaceAll(" ", "-") || ""}_${(title || key.replaceAll("@", "").toString()).replaceAll(" ", "-")}`
@@ -3704,7 +3734,7 @@ var Indi = class extends Common {
3704
3734
  if (!obje) {
3705
3735
  return;
3706
3736
  }
3707
- const key = `@O${index}@`;
3737
+ const key = objeXrefKey(obje, index);
3708
3738
  const isPrimary = obje?.get("_PRIM")?.toValue() === "Y";
3709
3739
  const url = obje?.get("FILE")?.toValue();
3710
3740
  const title = obje?.get("TITL")?.toValue() ?? "";
@@ -3721,6 +3751,7 @@ var Indi = class extends Common {
3721
3751
  imgId,
3722
3752
  person: this.id,
3723
3753
  title,
3754
+ note: objeNoteValue(obje),
3724
3755
  url,
3725
3756
  contentType: type,
3726
3757
  downloadName: `${this.id.replaceAll("@", "")}_${this.toNaturalName()?.replaceAll(" ", "-") || ""}_${(title || key.replaceAll("@", "").toString()).replaceAll(" ", "-")}`
@@ -3744,7 +3775,7 @@ var Indi = class extends Common {
3744
3775
  if (!obje) {
3745
3776
  return;
3746
3777
  }
3747
- const key = `@O${index}@`;
3778
+ const key = objeXrefKey(obje, index);
3748
3779
  obje.standardizeMedia();
3749
3780
  const isPrimary = obje?.get("_PRIM")?.toValue() === "Y";
3750
3781
  const url = obje?.get("FILE")?.toValue();
@@ -3761,6 +3792,7 @@ var Indi = class extends Common {
3761
3792
  imgId,
3762
3793
  person: this.id,
3763
3794
  title,
3795
+ note: objeNoteValue(obje),
3764
3796
  url,
3765
3797
  contentType: type,
3766
3798
  downloadName: `${this.id.replaceAll("@", "")}_${this.toNaturalName()?.replaceAll(" ", "-") || ""}_${(title || key.replaceAll("@", "").toString()).replaceAll(" ", "-")}`
@@ -3792,7 +3824,12 @@ var Indi = class extends Common {
3792
3824
  );
3793
3825
  if (cached !== void 0) {
3794
3826
  if (cached?.file && !isRemoteOrEmbeddedMediaUrl(cached.file)) {
3795
- const resolvedCached = await resolveLocalMediaUrl(cached.file);
3827
+ const resolvedCached = await resolveLocalMediaUrl(cached.file, {
3828
+ url: cached.file,
3829
+ person: this.id,
3830
+ tree: this.getTreeId?.(),
3831
+ treeName: this.getTreeName?.()
3832
+ });
3796
3833
  if (resolvedCached && isRemoteOrEmbeddedMediaUrl(resolvedCached)) {
3797
3834
  const refreshed = { ...cached, file: resolvedCached };
3798
3835
  profilePictureCache(
@@ -3817,7 +3854,16 @@ var Indi = class extends Common {
3817
3854
  }
3818
3855
  const mediaArray = Object.values(mediaList);
3819
3856
  const toDisplayableProfile = async (media, isPrimary) => {
3820
- const resolvedFile = await resolveLocalMediaUrl(media.url);
3857
+ const resolvedFile = await resolveLocalMediaUrl(media.url, {
3858
+ url: media.url,
3859
+ id: media.id,
3860
+ imgId: media.imgId,
3861
+ key: media.key,
3862
+ contentType: media.contentType,
3863
+ person: media.person || this.id,
3864
+ tree: media.tree || this.getTreeId?.(),
3865
+ treeName: this.getTreeName?.()
3866
+ });
3821
3867
  if (!resolvedFile || !isRemoteOrEmbeddedMediaUrl(resolvedFile)) {
3822
3868
  return void 0;
3823
3869
  }